GithubHelp home page GithubHelp logo

systemd / python-systemd Goto Github PK

View Code? Open in Web Editor NEW
463.0 19.0 66.0 414 KB

Python wrappers for systemd functionality

License: GNU Lesser General Public License v2.1

Emacs Lisp 0.12% Makefile 1.41% Python 32.74% C 65.73%

python-systemd's Introduction

python-systemd

Python module for native access to the systemd facilities. Functionality is separated into a number of modules:

  • systemd.journal supports sending of structured messages to the journal and reading journal files,
  • systemd.daemon wraps parts of libsystemd useful for writing daemons and socket activation,
  • systemd.id128 provides functions for querying machine and boot identifiers and a lists of message identifiers provided by systemd,
  • systemd.login wraps parts of libsystemd used to query logged in users and available seats and machines.

Installation

This module should be packaged for almost all Linux distributions. Use

On Fedora:

dnf install python3-systemd

On Debian/Ubuntu/Mint:

apt update
apt install python3-systemd

On openSUSE and SLE:

zypper in python3-systemd

On Arch:

pacman -Sy python-systemd

The project is also available on pypi as systemd-python:

PyPI

To build from source

On CentOS, RHEL, and Fedora:

dnf install git python3-pip gcc python3-devel systemd-devel
pip3 install 'git+https://github.com/systemd/python-systemd.git#egg=systemd-python'

On Debian or Ubuntu:

apt install libsystemd-{journal,daemon,login,id128}-dev gcc python3-dev pkg-config

Usage

Quick example:

from systemd import journal
journal.send('Hello world')
journal.send('Hello, again, world', FIELD2='Greetings!', FIELD3='Guten tag')
journal.send('Binary message', BINARY=b'\xde\xad\xbe\xef')

There is one required argument โ€” the message, and additional fields can be specified as keyword arguments. Following the journald API, all names are uppercase.

The journald sendv call can also be accessed directly:

from systemd import journal
journal.sendv('MESSAGE=Hello world')
journal.sendv('MESSAGE=Hello, again, world', 'FIELD2=Greetings!',
               'FIELD3=Guten tag')
journal.sendv('MESSAGE=Binary message', b'BINARY=\xde\xad\xbe\xef')

The two examples should give the same results in the log.

Reading from the journal is often similar to using the journalctl utility.

Show all entries since 20 minutes ago (journalctl --since "20 minutes ago"):

from systemd import journal
from datetime import datetime, timedelta
j = journal.Reader()
j.seek_realtime(datetime.now() - timedelta(minutes=20))
for entry in j:
    print(entry['MESSAGE'])

Show entries between two timestamps (journalctl --since "50 minutes ago" --until "10 minutes ago"):

from systemd import journal
from datetime import datetime, timedelta
j = journal.Reader()
since = datetime.now() - timedelta(minutes=50)
until = datetime.now() - timedelta(minutes=10)
j.seek_realtime(since)
for entry in j:
  if entry['__REALTIME_TIMESTAMP'] > until:
    break
  print(entry['MESSAGE'])

Show explanations of log messages alongside entries (journalctl -x):

from systemd import journal
j = journal.Reader()
for entry in j:
    print("MESSAGE: ", entry['MESSAGE'])
    try:
        print("CATALOG: ", j.get_catalog())
    except:
        pass

Show entries by a specific executable (journalctl /usr/bin/vim):

from systemd import journal
j = journal.Reader()
j.add_match('_EXE=/usr/bin/vim')
for entry in j:
    print(entry['MESSAGE'])
  • Note: matches can be added from many different fields, for example entries from a specific process ID can be matched with the _PID field, and entries from a specific unit (ie. journalctl -u systemd-udevd.service) can be matched with _SYSTEMD_UNIT. See all fields available at the systemd.journal-fields docs.

Show kernel ring buffer (journalctl -k):

from systemd import journal
j = journal.Reader()
j.add_match('_TRANSPORT=kernel')
for entry in j:
    print(entry['MESSAGE'])

Read entries in reverse (journalctl _EXE=/usr/bin/vim -r):

from systemd import journal
class ReverseReader(journal.Reader):
    def __next__(self):
        ans = self.get_previous()
        if ans:
            return ans
        raise StopIteration()

j = ReverseReader()
j.add_match('_EXE=/usr/bin/vim')
j.seek_tail()
for entry in j:
  print(entry['MESSAGE'])

Notes

  • Unlike the native C version of journald's sd_journal_send(), printf-style substitution is not supported. Perform any substitution using Python's f-strings first (or .format() or the % operator).
  • A ValueError is raised if sd_journald_sendv() results in an error. This might happen if there are no arguments or one of them is invalid.

A handler class for the Python logging framework is also provided:

import logging
from systemd import journal
logger = logging.getLogger('custom_logger_name')
logger.addHandler(journal.JournalHandler(SYSLOG_IDENTIFIER='custom_unit_name'))
logger.warning("Some message: %s", 'detail')

libsystemd version compatibility

This module may be compiled against any version of libsystemd. At compilation time, any functionality that is not available in that version is disabled, and the resulting binary module will depend on symbols that were available at compilation time. This means that the resulting binary module is compatible with that or any later version of libsystemd. To obtain maximum possible functionality, this module must be compile against suitably recent libsystemd.

Documentation

Online documentation can be found at freedesktop.org

To build it locally run:

make sphinx-html

Or use any other builder, see man sphinx-build for a list. The compiled docs will be e.g. in docs/html.

Viewing Output

Quick way to view output with all fields as it comes in:

sudo journalctl -f --output=json

Test Builds (for Development)

python setup.py build_ext -i
python
>>> from systemd import journal
>>> journal.send("Test")

Build Status

python-systemd's People

Contributors

alexole avatar alxchk avatar behrmann avatar davidstrauss avatar floppym avatar guiorgy avatar intgr avatar kaysievers avatar keszybz avatar kraj avatar kwirk avatar l2ol33rt avatar leolchat avatar lnykryn avatar marcelwaldvogel avatar mbiebl avatar moto-timo avatar mpaolini avatar mrc0mmand avatar nirs avatar otamachan avatar phomes avatar poettering avatar scop avatar sebix avatar sorki avatar thatguystone avatar weberhofer avatar wesleybowman avatar ytyt-yt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-systemd's Issues

RFE: provide hint if permissions do no allow any journal files to be opened

Reading from journald without permission to do so should throw an exception but doesn't?

build:~$ cat /etc/os-release 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

build:~$ 
build:~$ groups 
developers
build:~$ 
build:~$ journalctl --since "1 hour ago"
Hint: You are currently not seeing messages from other users and the system.
      Users in the 'systemd-journal' group can see all messages. Pass -q to
      turn off this notice.
No journal files were opened due to insufficient permissions.
build:~$ 
build:~$ python3.6
Python 3.6.3 (default, Jan  4 2018, 16:40:53) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> 
>>> from systemd import journal
>>> j = journal.Reader()
>>> j.this_boot()
>>> j.log_level(journal.LOG_DEBUG)
>>> j.get_next()
{}
>>> for entry in j:
...     print(entry)
... 
>>> 

Info on how to build this for systemd 239

I am following along with the facebook incubator for rpm-backports of systemd for Centos7. Currently they are at build 239 and I am attempting to replicate. It appears that python-systemd is no longer built in with systemd and the highest released version here is 234. When deploying systems with salt, it requires the python-systemd rpm. Can someone point me in the right direction on how to backport this to version 239 for centos7?

python-systemd doesn't build on CentOS 7 (systemd 208)

Using latest version in master:

building 'systemd/id128' extension

gcc -pthread -fno-strict-aliasing -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -DPACKAGE_VERSION="230" -DLIBSYSTEMD_JOURNAL_VERSION=208 -DLIBSYSTEMD_DAEMON_VERSION=208 -DLIBSYSTEMD_ID128_VERSION=208 -DLIBSYSTEMD_LOGIN_VERSION=208 -I/usr/include/python2.7 -c systemd/id128.c -o build/temp.linux-x86_64-2.7/systemd/id128.o

systemd/id128.c: In function โ€˜initid128โ€™:

systemd/id128.c:123:29: fatal error: id128-constants.h: No such file or directory

 #include "id128-constants.h"
                             ^
compilation terminated.

error: command 'gcc' failed with exit status 1

RHEL/CentOS 7 support on PyPI

I need this library on CentOS 7 using Python 3 from http://ius.io/ . As mentioned in #5, the current package on PyPI, i.e. the recent systemd-python==232, doesn't work on CentOS 7. from systemd import journal fails with undefined symbol: sd_journal_open_files_fd. (On a side note, I'm a bit confused as this project's README states that it's already packaged for Python 3 in the official RHEL/CentOS repos, but I can't find any sign of that, or even Python 3 itself).

As RHEL/CentOS are major distributions and represent a big chunk of people, I'd like to request that a compatible version of systemd-python be pushed to PyPI. Perhaps the support for sd_journal_open_files_fd can be made backward-compatible. Or maybe it would be necessary to push up an older build.

Performance analysis

When working with fail2ban, I noticed that some operations were really slow while reading from journal instead of text log files. This is not really noticeable with the default daemon operation of fail2ban, but more with its test tool called fail2ban-regex.

The main idea is that currently, all field's values are converted, which is completely uneeded for a lot of use cases. Moreover, the use of a ChainMap seems useless, but it is extremely costly, especially when no custom converters are provided.

I've implemented a test tool to monitor some possible improvements. Here are the raw results:
report_all

On the X axis, you can see patch sets, grouped by loads, that are further described. On the Y axis, these are number of cycles, as reported by perf (from the Linux kernel). The tests were performed with two sets:

  • One journal from openSuse Tumbleweed desktop: Intel Core i5-3320M, 138371 messages with 2928331 fields.
  • One journal from my Debian/testing server: Intel Core2 Duo E8400. I lost the figures, but it was roughly the same.

The chart above is from the Tumbleweed desktop, but the chart made using Core2 has strictly the same ratio. Only the numbers are a bit higher.

Loads

They are operations to be done with one journal entry. There are currently 4 of them:

  • empty: do nothing with the entry. This is a corner case.
  • digest: do some simple maths. It extracts two fields, _SYSTEMD_UNIT and MESSAGE.
  • fail2ban: extracted from fail2ban code, to format an entry in order to be parsed by fail2ban core logic.
  • read_all_fields: this reads all fields and values, and just count the fields. This is a corner case.

Patch sets

init_reader_nochainmap (aka nochainmap)

Currently, the Reader class uses a ChainMap to merge default converters and user provided ones. This is only done if Python version is greather or equal than 3.3. I've noticed that the time spent into the get() method is really high. It seems that ChainMap is good for merging either big dictionaries (where a call to update() is costly), or dynamic dictionaries (where an update into one dictonary is reflected into the ChainMap instance). It seems that Reader is not in any of these 2 cases, so this patche completely removes the use of ChainMap, copies the default converters dict, and updates it with custom converters if needed.

This is by far the easiest, less intrusive, and most efficient patch in all cases.

convert_entry_lazy

This is the first step of a convert-on-demand step. Instead of converting all field values in _convert_entry, we just return a MutableMapping with all already fetched values as bytes, and convert values only on request. Converted values are not recorded, since we assume the caller will not try to fetch the same field twice.

get_next() is untouched, so special fields (__CURSOR, __MONOTONIC_TIMESTAMP, __REALTIME_TIMESTAMP) are already fetched, but not converted.

This is a good approach, but there is nearly always a better way to do it, except for the read_all_fields corner case.

get_next_lazy (aka next_lazy)

This is an evolution of convert_entry_lazy, that modifies get_next() itself. By default, there is no call to _get_all(), and only an instance of Mapping is returned. Special fields are not even computed. When requested, a field is then fetched using _get() and then _convert_value(). Result is not recorded for the same reason.

To be able to iterate on this Mapping, the first call to __iter__ or __len__ will fetch all fields using _get_all(), add special field names, and record the result. A __bool__ method is also provided to avoid costly call to __len__() just to test if the current entry is valid (it is).

This is the best approach for cases where there is a small amount of fields to read, as in empty and digest loads.

get_next_lazy_prefetched (aka next_lazy_prefetched)

This is a mix between convert_entry_lazy and get_next_lazy, to show the effects of just calling _get_all(), without creating special entries. Values are only converted on request, and special fields are fetched and converted on request.

This is usually a better approach than convert_entry_lazy, except in read_all_fields, which I can't explain. As we can see in the digest load, the difference between this and get_next_lazy is minimal, so we can assume that calling _get_all() has a negligible impact, except for the empty corner case.

convert_value_nolist (immature)

This patch is not visible in the chart.

The goal is to remove the isinstance() test when converting values, since the vast majority of values are not list. The impact is not negligible, but I found some logs where values returned by _get_all are lists. The journal format has no such list, but field name can be duplicated, so _get_all gather them into lists. In my tests, I found 3 messages with such cases, using journal from openSuse Tumbleweed, with SYSLOG_IDENTIFIER field. On Debian/testing, I was not able to found this case.

Analysis

Disable ChainMap usage in all cases: this is always a win. I will open a merge request for this soon.

Use convert-on-demand: In nearly all cases, it is more interesting to call _get_all() without converting anything.

Import caveat for get_next_lazy: on request, it uses calls to _get(). If a field is duplicated, _get only returns the first value, while _get_all will gather all values in a list. This is notified in systemd/systemd#9696.

As a result of this, I would like to write a patch for get_next() that does the same job as get_next_lazy_prefetched by default, with an optional boolean (defaulted to True) for calling or not get_all. When set to False, it will be the same as get_next_lazy, with the important caveat mentioned before. But for small loads, it will be faster.

Conclusion

I would like to know if you have any thoughts about this:

  • is the cycles a good metric?
  • have I missed something about some edge cases in journal entries?
  • [โ€ฆ]

You can use run_all.sh in my own tool, that will write a report_aggregate.csv which is easy to turn into chart using LibreOffice or any other charting tool of your choice.

234: sphiinx warnings and errors

After apply patch below which migrates from distutils to setuptools

--- a//setup.py~        2017-03-26 02:33:59.000000000 +0100
+++ b//setup.py 2021-06-06 06:45:00.369493129 +0100
@@ -1,5 +1,5 @@
 import sys, os
-from distutils.core import setup, Extension
+from setuptools import setup, Extension
 from subprocess import Popen, PIPE, check_output

 def call(*cmd):
+ /usr/bin/python3 setup.py build_sphinx -b man --build-dir build/sphinx
running build_sphinx
Running Sphinx v4.0.2
making output directory... done
loading intersphinx inventory from http://docs.python.org/objects.inv...
intersphinx inventory has moved: http://docs.python.org/objects.inv -> https://docs.python.org/3/objects.inv
building [mo]: targets for 0 po files that are out of date
building [man]: all manpages
updating environment: [new config] 5 added, 0 changed, 0 removed
reading sources... [100%] login
WARNING: autodoc: failed to import module 'daemon' from module 'systemd'; the following exception was raised:
No module named 'systemd._daemon'
WARNING: autodoc: failed to import module 'id128' from module 'systemd'; the following exception was raised:
No module named 'systemd.id128'
WARNING: autodoc: failed to import module 'journal' from module 'systemd'; the following exception was raised:
No module named 'systemd._journal'
WARNING: don't know which module to import for autodocumenting 'JournalHandler' (try placing a "module" or "currentmodule" directive in the document, or giving an explicit module name)
WARNING: don't know which module to import for autodocumenting '_Reader' (try placing a "module" or "currentmodule" directive in the document, or giving an explicit module name)
WARNING: don't know which module to import for autodocumenting 'Reader' (try placing a "module" or "currentmodule" directive in the document, or giving an explicit module name)
WARNING: don't know which module to import for autodocumenting '_get_catalog' (try placing a "module" or "currentmodule" directive in the document, or giving an explicit module name)
WARNING: don't know which module to import for autodocumenting 'get_catalog' (try placing a "module" or "currentmodule" directive in the document, or giving an explicit module name)
WARNING: don't know which module to import for autodocumenting 'Monotonic' (try placing a "module" or "currentmodule" directive in the document, or giving an explicit module name)
WARNING: autodoc: failed to import attribute 'journal.DEFAULT_CONVERTERS' from module 'systemd'; the following exception was raised:
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 412, in safe_getattr
    return getattr(obj, name, *defargs)
AttributeError: module 'systemd' has no attribute 'journal'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/importer.py", line 110, in import_object
    obj = attrgetter(obj, mangled_name)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 318, in get_attr
    return autodoc_attrgetter(self.env.app, obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 2606, in autodoc_attrgetter
    return safe_getattr(obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 428, in safe_getattr
    raise AttributeError(name) from exc
AttributeError: journal

WARNING: autodoc: failed to import attribute 'journal.LOCAL_ONLY' from module 'systemd'; the following exception was raised:
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 412, in safe_getattr
    return getattr(obj, name, *defargs)
AttributeError: module 'systemd' has no attribute 'journal'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/importer.py", line 110, in import_object
    obj = attrgetter(obj, mangled_name)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 318, in get_attr
    return autodoc_attrgetter(self.env.app, obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 2606, in autodoc_attrgetter
    return safe_getattr(obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 428, in safe_getattr
    raise AttributeError(name) from exc
AttributeError: journal

WARNING: autodoc: failed to import attribute 'journal.RUNTIME_ONLY' from module 'systemd'; the following exception was raised:
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 412, in safe_getattr
    return getattr(obj, name, *defargs)
AttributeError: module 'systemd' has no attribute 'journal'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/importer.py", line 110, in import_object
    obj = attrgetter(obj, mangled_name)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 318, in get_attr
    return autodoc_attrgetter(self.env.app, obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 2606, in autodoc_attrgetter
    return safe_getattr(obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 428, in safe_getattr
    raise AttributeError(name) from exc
AttributeError: journal

WARNING: autodoc: failed to import attribute 'journal.SYSTEM' from module 'systemd'; the following exception was raised:
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 412, in safe_getattr
    return getattr(obj, name, *defargs)
AttributeError: module 'systemd' has no attribute 'journal'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/importer.py", line 110, in import_object
    obj = attrgetter(obj, mangled_name)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 318, in get_attr
    return autodoc_attrgetter(self.env.app, obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 2606, in autodoc_attrgetter
    return safe_getattr(obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 428, in safe_getattr
    raise AttributeError(name) from exc
AttributeError: journal

WARNING: autodoc: failed to import attribute 'journal.CURRENT_USER' from module 'systemd'; the following exception was raised:
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 412, in safe_getattr
    return getattr(obj, name, *defargs)
AttributeError: module 'systemd' has no attribute 'journal'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/importer.py", line 110, in import_object
    obj = attrgetter(obj, mangled_name)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 318, in get_attr
    return autodoc_attrgetter(self.env.app, obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 2606, in autodoc_attrgetter
    return safe_getattr(obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 428, in safe_getattr
    raise AttributeError(name) from exc
AttributeError: journal

WARNING: autodoc: failed to import attribute 'journal.OS_ROOT' from module 'systemd'; the following exception was raised:
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 412, in safe_getattr
    return getattr(obj, name, *defargs)
AttributeError: module 'systemd' has no attribute 'journal'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/importer.py", line 110, in import_object
    obj = attrgetter(obj, mangled_name)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 318, in get_attr
    return autodoc_attrgetter(self.env.app, obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 2606, in autodoc_attrgetter
    return safe_getattr(obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 428, in safe_getattr
    raise AttributeError(name) from exc
AttributeError: journal

WARNING: autodoc: failed to import attribute 'journal.NOP' from module 'systemd'; the following exception was raised:
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 412, in safe_getattr
    return getattr(obj, name, *defargs)
AttributeError: module 'systemd' has no attribute 'journal'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/importer.py", line 110, in import_object
    obj = attrgetter(obj, mangled_name)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 318, in get_attr
    return autodoc_attrgetter(self.env.app, obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 2606, in autodoc_attrgetter
    return safe_getattr(obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 428, in safe_getattr
    raise AttributeError(name) from exc
AttributeError: journal

WARNING: autodoc: failed to import attribute 'journal.APPEND' from module 'systemd'; the following exception was raised:
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 412, in safe_getattr
    return getattr(obj, name, *defargs)
AttributeError: module 'systemd' has no attribute 'journal'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/importer.py", line 110, in import_object
    obj = attrgetter(obj, mangled_name)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 318, in get_attr
    return autodoc_attrgetter(self.env.app, obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 2606, in autodoc_attrgetter
    return safe_getattr(obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 428, in safe_getattr
    raise AttributeError(name) from exc
AttributeError: journal

WARNING: autodoc: failed to import attribute 'journal.INVALIDATE' from module 'systemd'; the following exception was raised:
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 412, in safe_getattr
    return getattr(obj, name, *defargs)
AttributeError: module 'systemd' has no attribute 'journal'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/importer.py", line 110, in import_object
    obj = attrgetter(obj, mangled_name)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 318, in get_attr
    return autodoc_attrgetter(self.env.app, obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/ext/autodoc/__init__.py", line 2606, in autodoc_attrgetter
    return safe_getattr(obj, name, *defargs)
  File "/usr/lib/python3.8/site-packages/sphinx/util/inspect.py", line 428, in safe_getattr
    raise AttributeError(name) from exc
AttributeError: journal

WARNING: autodoc: failed to import module 'login' from module 'systemd'; the following exception was raised:
No module named 'systemd.login'
WARNING: don't know which module to import for autodocumenting 'Monitor' (try placing a "module" or "currentmodule" directive in the document, or giving an explicit module name)
looking for now-outdated files... none found
pickling environment... done
checking consistency... done
writing... python-systemd.1 { journal id128 daemon login } done
build succeeded, 20 warnings.

uids and sessions returned by login.uids() and login.sessions() are not in order

I noticed the login.uids() and login.sessions() report their results without any meaningful order.
That is, one can not determine which session belongs to which uid.
This is an example demonstrating the difference between what is given by the mentioned methods and what is given by the loginctl list-sessions:

uids = login.uids()
sessionsd = login.sessions()
INFO:root:uids: [121, 1000]
INFO:root:sessions: ['2', 'c1']

the output of loginctl list-sessions:

INFO:root:sessions: 
SESSION        UID     USER        SEAT           TTY             
   2          1000    hossein      seat0          tty2            
  c1          121      gdm         seat0          tty1            

2 sessions listed.

As you can see it seems the lists are sorted which shouldn't be the case as it makes it impossible to couple uid with a respective session id.

it would however, make more sense imho, to have a new method that returns the uid:sessionid pair (it can contain more than session id, but thats just an example for our specific case), but until then, they need to at least have the same order for them to be usable

seek_realtime: seconds or microseconds?

https://github.com/systemd/python-systemd/blob/master/systemd/_reader.c

Reader_seek_realtime states (in docstring) that the argument realtime is number of seconds (perhaps since the Unix epoch), but calls the sd_journal_seek_realtime_usec, that is, treats the argument as microseconds (usec).

In https://github.com/systemd/python-systemd/blob/master/systemd/journal.py, in seek_realtime, the argument is said to be "an integer unix timestamp" - which, as far as I know, means seconds (since the epoch). There is no mention of microseconds.

JournalHandler: set journald unit

Daemons need to be able to generate logs with the same unit name configured in the systemd unit file.
JournalHandler should provide a way to do so and document it as as recommended pattern.

C90 compatibility is only enforced in the CI

Running make or make check on the local system does not complain about C99 constructs (such as defining the loop variable in the loop itself, e.g. 2596c5d).

This makes it hard to create code which passes CI.

Can this be changed in the Makefile? Or can the requirement to be C90 compatible be relaxed?

Cannot install on CentOS 7

Linux 3.10.0-327.36.3.el7.x86_64
Python 3.5.2 (default, Jun 27 2016, 14:02:55)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] on linux
systemd 219


$ dnf install python3-systemd

Using metadata from Thu Apr 13 14:55:29 2017
No package python3-systemd available.
Error: no package matched: python3-systemd


$ dnf install python-systemd

Using metadata from Thu Apr 13 14:55:29 2017
No package python-systemd available.
Error: no package matched: python-systemd


$ pip3 install git+https://github.com/systemd/python-systemd.git#egg=systemd

Collecting systemd from git+https://github.com/systemd/python-systemd.git#egg=systemd
Cloning https://github.com/systemd/python-systemd.git to /tmp/pip-build-13uuw3rj/systemd
Complete output from command python setup.py egg_info:
Cannot find libsystemd or libsystemd-journal:

Package libsystemd was not found in the pkg-config search path.
Perhaps you should add the directory containing `libsystemd.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libsystemd' found

Package libsystemd-journal was not found in the pkg-config search path.
Perhaps you should add the directory containing `libsystemd-journal.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libsystemd-journal' found
----------------------------------------

$ pip install systemd-python
Collecting systemd-python
Using cached systemd-python-234.tar.gz
Complete output from command python setup.py egg_info:
Cannot find libsystemd or libsystemd-journal:

Package libsystemd was not found in the pkg-config search path.
Perhaps you should add the directory containing `libsystemd.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libsystemd' found

Package libsystemd-journal was not found in the pkg-config search path.
Perhaps you should add the directory containing `libsystemd-journal.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libsystemd-journal' found

Hardcoding of file path of "sd-messages.h" preventing using this in build systems

Hi,

We are trying to build python-systemd for a different architecture using yocto build system, but due to the hardcoding of the file path of sd-messages.h in setup.py we are unable to do so unless the systemd header files are installed on the build system and are of the same version as that of the target build

Offending lines:

constants = [line.split()[1]
                         for line in open("/usr/include/systemd/sd-messages.h")
                         if line.startswith('#define SD_MESSAGE_')]

The code should instead take a relative path to systemd headers and use that instead of the absolute path. Will send you out a pull request for the same if it is acceptable or please suggest an alternative.

Start, Stop, Restart services examples?

Would be nice to see some documentation on starting, restarting and check status on the services on the README.
Looking at the man pages, it seems I should be using the service handler, but I would like to see some code example.

Installation in Debian 8.2 Systemd-nspawn container fails: OSError: [Errno 2] No such file or directory

Hi,
following the installation instructions from https://github.com/systemd/python-systemd/blob/master/README.md I would like to use python-systemd (Python2.7) in a systemd-nspawn container with Debian 8.2 OS.

I tried to install the Debian distribution, but it is not found:

sudo apt-get install python-systemd 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package python-systemd

Installing the dev dependencies works:

apt-get install libsystemd-{journal,daemon,login,id128}-dev gcc python-dev
[โ€ฆ]
gcc is already the newest version.
python-dev is already the newest version.
libsystemd-daemon-dev is already the newest version.
libsystemd-id128-dev is already the newest version.
libsystemd-journal-dev is already the newest version.
libsystemd-login-dev is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

But when I try one of the following installation methods, I get an error.
Using pip:

pip install git+https://github.com/systemd/python-systemd.git#egg=systemd
Downloading/unpacking systemd from git+https://github.com/systemd/python-systemd.git
  Cloning https://github.com/systemd/python-systemd.git to /tmp/pip-build-62myFr/systemd
  Running setup.py (path:/tmp/pip-build-62myFr/systemd/setup.py) egg_info for package systemd
    Traceback (most recent call last):
      File "<string>", line 17, in <module>
      File "/tmp/pip-build-62myFr/systemd/setup.py", line 64, in <module>
    **lib('libsystemd', 'libsystemd-journal', **defines))
      File "/tmp/pip-build-62myFr/systemd/setup.py", line 50, in lib
    status, result = pkgconfig(name, **kw)
      File "/tmp/pip-build-62myFr/systemd/setup.py", line 32, in pkgconfig
    status, result = call('pkg-config', '--libs', '--cflags', package)
      File "/tmp/pip-build-62myFr/systemd/setup.py", line 24, in call
    universal_newlines=True)
      File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
      File "/usr/lib/python2.7/subprocess.py", line 1335, in _execute_child
    raise child_exception
    OSError: [Errno 2] No such file or directory
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
  File "<string>", line 17, in <module>
  File "/tmp/pip-build-62myFr/systemd/setup.py", line 64, in <module>
    **lib('libsystemd', 'libsystemd-journal', **defines))
  File "/tmp/pip-build-62myFr/systemd/setup.py", line 50, in lib
    status, result = pkgconfig(name, **kw)
  File "/tmp/pip-build-62myFr/systemd/setup.py", line 32, in pkgconfig
    status, result = call('pkg-config', '--libs', '--cflags', package)
  File "/tmp/pip-build-62myFr/systemd/setup.py", line 24, in call
    universal_newlines=True)
  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1335, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory
----------------------------------------
Cleaning up...
Command python setup.py egg_info failed with error code 1 in /tmp/pip-build-62myFr/systemd
Storing debug log for failure in /root/.pip/pip.log

the same using setup.py install directly:

python-systemd$ python setup.py install
Traceback (most recent call last):
  File "setup.py", line 64, in <module>
    **lib('libsystemd', 'libsystemd-journal', **defines))
  File "setup.py", line 50, in lib
    status, result = pkgconfig(name, **kw)
  File "setup.py", line 32, in pkgconfig
    status, result = call('pkg-config', '--libs', '--cflags', package)
  File "setup.py", line 24, in call
    universal_newlines=True)
  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1335, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

TIA, regards Udo

Version 233 test-issues while building for openSUSE Leap 42.1

The systemd version is "210"

_______________________ [doctest] systemd.journal.stream _______________________
450 Return a file object wrapping a stream to journal.
451 
452     Log messages written to this file as simple newline sepearted text strings
453     are written to the journal.
454 
455     The file will be line buffered, so messages are actually sent after a
456     newline character is written.
457 
458     >>> from systemd import journal
459     >>> stream = journal.stream('myapp')
UNEXPECTED EXCEPTION: IOError(2, 'No such file or directory')
Traceback (most recent call last):

  File "/usr/lib64/python2.7/doctest.py", line 1315, in __run
    compileflags, 1) in test.globs

  File "<doctest systemd.journal.stream[1]>", line 1, in <module>

  File "/home/abuild/rpmbuild/BUILD/python-systemd-233/build/lib.linux-x86_64-2.7/systemd/journal.py", line 489, in stream
    fd = stream_fd(identifier, priority, level_prefix)

IOError: [Errno 2] No such file or directory

/home/abuild/rpmbuild/BUILD/python-systemd-233/build/lib.linux-x86_64-2.7/systemd/journal.py:459: UnexpectedException
____________________________ test_notify_no_socket _____________________________

    def test_notify_no_socket():
        assert notify('READY=1') == False
        with skip_enosys():
>           assert notify('FDSTORE=1', fds=[]) == False
E           NotImplementedError: Compiled without support for sd_pid_notify_with_fds

systemd/test/test_daemon.py:213: NotImplementedError
____________________________ test_notify_bad_socket ____________________________

    def test_notify_bad_socket():
        os.environ['NOTIFY_SOCKET'] = '/dev/null'
    
        with pytest.raises(connection_error):
            notify('READY=1')
        with pytest.raises(connection_error):
            with skip_enosys():
>               notify('FDSTORE=1', fds=[])
E               NotImplementedError: Compiled without support for sd_pid_notify_with_fds

systemd/test/test_daemon.py:230: NotImplementedError
___________________________ test_notify_with_socket ____________________________

tmpdir = local('/tmp/pytest-of-abuild/pytest-1/test_notify_with_socket0')

    def test_notify_with_socket(tmpdir):
        path = tmpdir.join('socket').strpath
        sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
        sock.bind(path)
        # SO_PASSCRED is not defined in python2.7
        SO_PASSCRED = getattr(socket, 'SO_PASSCRED', 16)
        sock.setsockopt(socket.SOL_SOCKET, SO_PASSCRED, 1)
        os.environ['NOTIFY_SOCKET'] = path
    
        assert notify('READY=1') == True
        with skip_enosys():
>           assert notify('FDSTORE=1', fds=[]) == True
E           NotImplementedError: Compiled without support for sd_pid_notify_with_fds

systemd/test/test_daemon.py:249: NotImplementedError
_____________________________ [doctest] login.rst ______________________________
011 Example: polling for events
012 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
013 
014 This example shows that session/uid/seat/machine events can be waited
015 for (using e.g. `poll`). This makes it easy to integrate Monitor in an
016 external event loop:
017 
018   >>> import select
019   >>> from systemd import login
020   >>> m = login.Monitor("machine")
UNEXPECTED EXCEPTION: OSError(2, 'No such file or directory')
Traceback (most recent call last):

  File "/usr/lib64/python2.7/doctest.py", line 1315, in __run
    compileflags, 1) in test.globs

  File "<doctest login.rst[2]>", line 1, in <module>

OSError: [Errno 2] No such file or directory

/home/abuild/rpmbuild/BUILD/python-systemd-233/docs/login.rst:20: UnexpectedException
================ 5 failed, 35 passed, 5 skipped in 0.15 seconds ================
Makefile:54: recipe for target 'check' failed
make: *** [check] Error 1
error: Bad exit status from /var/tmp/rpm-tmp.2wPiyk (%check)

Time for a new release (v235)?

Can we get a new release of this python module? it contains code that would be pretty useful (in particular, #60 would be handy for me), but it's easier to deploy if those changes are part of an official upstream release.

the last release (v234) appears to have been made over 2 years ago.

journal.Reader.add_match() does not support glob matching

Versions:

  • Debian 9 (Stretch)
  • python3 3.5.3-1
  • python3-system 233-1
  • systemd 232-25+deb9u
    ... but as far as I can tell from _reader.c it applies to master (a402d08) as well.

For example:

journal_reader.add_match(_SYSTEMD_UNIT="kres*")

always returns empty output. At the same time command journalctl -u 'kres*' lists log for units kresd@dns1, kresd@dns2, kres-cache-gc etc.

It would be nice if the Python API could do the same. For now I'm going to resort calling journalctl as subprocess.

Build/test problems on openSUSE

With the current release 231, some tests fail within the build-environment. Do you have any hint how to solve that?

[   23s] + make -j8 check
[   23s] /bin/sh: git: command not found
[   23s] python setup.py build
[   23s] running build
[   23s] running build_py
[   23s] package init file 'systemd/test/__init__.py' not found (or not a regular file)
[   23s] package init file 'systemd/test/__init__.py' not found (or not a regular file)
[   23s] running build_ext
[   23s] (cd build/lib.linux-x86_64-2.7 && python -m py.test . ../../docs -v)
[   23s] ============================= test session starts ==============================
[   23s] platform linux2 -- Python 2.7.9, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- /usr/bin/python
[   23s] cachedir: ../../.cache
[   23s] rootdir: /home/abuild/rpmbuild/BUILD/python-systemd-231, inifile: pytest.ini
[   23s] collecting ... collected 38 items
[   23s] 
[   23s] systemd/journal.py::systemd.journal.JournalHandler PASSED
[   23s] systemd/journal.py::systemd.journal.Reader PASSED
[   23s] systemd/journal.py::systemd.journal.send PASSED
[   23s] systemd/journal.py::systemd.journal.stream FAILED
[   23s] systemd/test/test_daemon.py::test_booted PASSED
[   23s] systemd/test/test_daemon.py::test__is_fifo PASSED
[   23s] systemd/test/test_daemon.py::test__is_fifo_file PASSED
[   23s] systemd/test/test_daemon.py::test__is_fifo_bad_fd PASSED
[   23s] systemd/test/test_daemon.py::test_is_fifo PASSED
[   23s] systemd/test/test_daemon.py::test_is_fifo_file PASSED
[   23s] systemd/test/test_daemon.py::test_is_fifo_bad_fd PASSED
[   23s] systemd/test/test_daemon.py::test_no_mismatch PASSED
[   23s] systemd/test/test_daemon.py::test_is_socket PASSED
[   23s] systemd/test/test_daemon.py::test__is_socket PASSED
[   23s] systemd/test/test_daemon.py::test_is_socket_unix PASSED
[   23s] systemd/test/test_daemon.py::test__is_socket_unix PASSED
[   23s] systemd/test/test_daemon.py::test_listen_fds_no_fds PASSED
[   23s] systemd/test/test_daemon.py::test_listen_fds PASSED
[   23s] systemd/test/test_daemon.py::test_listen_fds_default_unset PASSED
[   24s] systemd/test/test_daemon.py::test_notify_no_socket FAILED
[   24s] systemd/test/test_daemon.py::test_notify_bad_socket FAILED
[   24s] systemd/test/test_daemon.py::test_notify_with_socket FAILED
[   24s] systemd/test/test_journal.py::test_priorities PASSED
[   24s] systemd/test/test_journal.py::test_journalhandler_init_exception PASSED
[   24s] systemd/test/test_journal.py::test_journalhandler_init PASSED
[   24s] systemd/test/test_journal.py::test_reader_init_flags PASSED
[   24s] systemd/test/test_journal.py::test_reader_init_path PASSED
[   24s] systemd/test/test_journal.py::test_reader_as_cm PASSED
[   24s] systemd/test/test_journal.py::test_reader_messageid_match PASSED
[   24s] systemd/test/test_journal.py::test_reader_this_boot PASSED
[   24s] systemd/test/test_journal.py::test_reader_this_machine PASSED
[   24s] systemd/test/test_journal.py::test_reader_converters PASSED
[   24s] systemd/test/test_journal.py::test_reader_convert_entry PASSED
[   24s] ../../docs/daemon.rst SKIPPED
[   24s] ../../docs/id128.rst SKIPPED
[   24s] ../../docs/index.rst SKIPPED
[   24s] ../../docs/journal.rst PASSED
[   24s] ../../docs/login.rst FAILED
[   24s] 
[   24s] =================================== FAILURES ===================================
[   24s] _______________________ [doctest] systemd.journal.stream _______________________
[   24s] 414     r"""Return a file object wrapping a stream to journal.
[   24s] 415 
[   24s] 416     Log messages written to this file as simple newline sepearted text
[   24s] 417     strings are written to the journal.
[   24s] 418 
[   24s] 419     The file will be line buffered, so messages are actually sent
[   24s] 420     after a newline character is written.
[   24s] 421 
[   24s] 422     >>> from systemd import journal
[   24s] 423     >>> stream = journal.stream('myapp')
[   24s] UNEXPECTED EXCEPTION: IOError(2, 'No such file or directory')
[   24s] Traceback (most recent call last):
[   24s] 
[   24s]   File "/usr/lib64/python2.7/doctest.py", line 1315, in __run
[   24s]     compileflags, 1) in test.globs
[   24s] 
[   24s]   File "<doctest systemd.journal.stream[1]>", line 1, in <module>
[   24s] 
[   24s]   File "/home/abuild/rpmbuild/BUILD/python-systemd-231/build/lib.linux-x86_64-2.7/systemd/journal.py", line 446, in stream
[   24s]     fd = stream_fd(identifier, priority, level_prefix)
[   24s] 
[   24s] IOError: [Errno 2] No such file or directory
[   24s] 
[   24s] /home/abuild/rpmbuild/BUILD/python-systemd-231/build/lib.linux-x86_64-2.7/systemd/journal.py:423: UnexpectedException
[   24s] ____________________________ test_notify_no_socket _____________________________
[   24s] 
[   24s]     def test_notify_no_socket():
[   24s]         assert notify('READY=1') == False
[   24s] >       assert notify('FDSTORE=1', fds=[]) == False
[   24s] E       NotImplementedError: Compiled without support for sd_pid_notify_with_fds
[   24s] 
[   24s] systemd/test/test_daemon.py:203: NotImplementedError
[   24s] ____________________________ test_notify_bad_socket ____________________________
[   24s] 
[   24s]     def test_notify_bad_socket():
[   24s]         os.environ['NOTIFY_SOCKET'] = '/dev/null'
[   24s]     
[   24s]         with pytest.raises(connection_error):
[   24s]             notify('READY=1')
[   24s]         with pytest.raises(connection_error):
[   24s] >           notify('FDSTORE=1', fds=[])
[   24s] E           NotImplementedError: Compiled without support for sd_pid_notify_with_fds
[   24s] 
[   24s] systemd/test/test_daemon.py:219: NotImplementedError
[   24s] ___________________________ test_notify_with_socket ____________________________
[   24s] 
[   24s] tmpdir = local('/tmp/pytest-of-abuild/pytest-2/test_notify_with_socket0')
[   24s] 
[   24s]     def test_notify_with_socket(tmpdir):
[   24s]         path = tmpdir.join('socket').strpath
[   24s]         sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
[   24s]         sock.bind(path)
[   24s] >       sock.setsockopt(socket.SOL_SOCKET, socket.SO_PASSCRED, 1)
[   24s] E       AttributeError: 'module' object has no attribute 'SO_PASSCRED'
[   24s] 
[   24s] systemd/test/test_daemon.py:231: AttributeError
[   24s] ___________________________ [doctest] docs/login.rst ___________________________
[   24s] 011 Example: polling for events
[   24s] 012 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
[   24s] 013 
[   24s] 014 This example shows that session/uid/seat/machine events can be waited
[   24s] 015 for (using e.g. `poll`). This makes it easy to integrate Monitor in an
[   24s] 016 external event loop:
[   24s] 017 
[   24s] 018   >>> import select
[   24s] 019   >>> from systemd import login
[   24s] 020   >>> m = login.Monitor("machine")
[   24s] UNEXPECTED EXCEPTION: OSError(2, 'No such file or directory')
[   24s] Traceback (most recent call last):
[   24s] 
[   24s]   File "/usr/lib64/python2.7/doctest.py", line 1315, in __run
[   24s]     compileflags, 1) in test.globs
[   24s] 
[   24s]   File "<doctest login.rst[2]>", line 1, in <module>
[   24s] 
[   24s] OSError: [Errno 2] No such file or directory
[   24s] 
[   24s] /home/abuild/rpmbuild/BUILD/python-systemd-231/docs/login.rst:20: UnexpectedException
[   24s] ================ 5 failed, 30 passed, 3 skipped in 0.29 seconds ================
[   24s] Makefile:39: recipe for target 'check' failed
[   24s] make: *** [check] Error 1
[   24s] error: Bad exit status from /var/tmp/rpm-tmp.mi76ss (%check)

Additionally, there are two compiler-notes I see during compilation:

[   20s] systemd/_reader.c: In function 'Reader_next':
[   20s] systemd/_reader.c:360:22: warning: 'r' may be used uninitialized in this function [-Wmaybe-uninitialized]
[   20s]          if (set_error(r, NULL, NULL) < 0)
[   20s] systemd/_daemon.c: In function 'notify':
[   20s] systemd/_daemon.c:79:28: warning: variable 'n_fds' set but not used [-Wunused-but-set-variable]
[   20s]          int unset = false, n_fds;

JournalHandler incorrectly send exception info

https://github.com/systemd/python-systemd/blob/master/systemd/journal.py#L581-L586

record.exc_text is a cache for text representation of record.exc_info https://github.com/python/cpython/blob/master/Lib/logging/__init__.py#L335
record.exc_info is a tuple https://github.com/python/cpython/blob/master/Lib/logging/__init__.py#L1579
So send str(record.exc_info) is unnecessary. There is a default implementation in formatter https://github.com/python/cpython/blob/master/Lib/logging/__init__.py#L681-L689

Also we send information about exception but no record.stack_info it's could be useful as well.

Cannot install on CentOS 7

Tried:
dnf install python-systemd python3-systemd

result:
Error: Unable to find a match: python-systemd python3-systemd

and:

sudo pip3 install git+https://github.com/systemd/python-systemd.git#egg=systemd
Traceback (most recent call last):
  File "/bin/pip3", line 16, in <module>
    sys.exit(main())
TypeError: 'module' object is not callable

Can't filter using "_SYSTEMD_UNIT"

I want to monitor the journal of a running vpn-client unit. To do so I first used sudo journalctl -f --output=json to get an idea of the general structure of each entry's catalog (unimportant information truncated):

{
  "SYSLOG_IDENTIFIER" : "openvpn",
  "_COMM" : "openvpn",
  "_EXE" : "/usr/bin/openvpn",
  "_CMDLINE" : "/usr/sbin/openvpn --suppress-timestamps --nobind --config VPN.conf",
  "_SYSTEMD_CGROUP" : "/system.slice/system-openvpn\\x2dclient.slice/[email protected]",
  "_SYSTEMD_UNIT" : "[email protected]",
  "_SYSTEMD_SLICE" : "system-openvpn\\x2dclient.slice",
  "MESSAGE" : "...",
  "_PID" : "4586"
}

Based on this, I figured I could use .add_match(_SYSTEMD_UNIT='[email protected]') as documented to get access to the corresponding journal.

However I can't seem to fetch and journal entries when doing so:

reader = systemd.journal.Reader()
reader.this_boot()
reader.add_match(_SYSTEMD_UNIT='[email protected]')
for entry in reader:
    print(entry)

Will simply print nothing, while confusingly (to me) specifying the SYSLOG_IDENTIFIER instead will work:

reader = systemd.journal.Reader()
reader.this_boot()
reader.add_match(SYSLOG_IDENTIFIER='openvpn')
for entry in reader:
    print(entry)

However this fetches the entries of all openvpn journals, which I don't want. I also made sure using journalctl --boot --unit [email protected] that journal entries matching the specified filter exist. (Removing the this_boot()-filter also doesn't lead to any entries being fetched).

Any advice?

systemd/id128.c:149:29: fatal error: id128-constants.h: No such file or directory

systemd/id128.c: In function โ€˜PyInit_id128โ€™:
systemd/id128.c:149:29: fatal error: id128-constants.h: No such file or directory
compilation terminated.
error: command 'gcc' failed with exit status 1
==> ERROR: A failure occurred in build().
    Aborting...

This is fixed in the master, but needs a new tagged release to fix it.

Thanks
Daniel

JournalHandler: Sanitize extra fields to be valid journald fields

I noticed an incontinence with JournalHandler when using it in an existing code base. I already use the Python logging module and all my logging already includes structured data like this:

LOG.info('test', extra={'structured_data': 23})

The structured_data field does not make it into journald and is silently omitted. I checked https://github.com/mosquito/cysystemd and it has sanitation code which works for me:

https://github.com/mosquito/cysystemd/blob/e0acede93387d51e4d6b20fdc278b2675052958d/cysystemd/_journal.pyx#L26-L34

As the status of this project and relationship with https://github.com/mosquito/cysystemd is not clear I just wanted to document this here.

Edit:

I ended up using python-systemd instead of cysystemd mainly because of the less cluttered fields it outputs so I needed to work around the issue described here. I needed to workaround another limitation which is that journald cannot handle nested fields so I combined the two workarounds into this (also I want to log sets so it includes a workaround for this as well):

import logging
import json

from systemd.journal import JournalHandler


class SetJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, set):
            return list(obj)
        return json.JSONEncoder.default(self, obj)


class LogExtraAsJsonDataAdapter(logging.LoggerAdapter):
    def process(self, msg, kwargs):
        if 'extra' in kwargs:
            kwargs['extra'] = {'JSON_SD': json.dumps(kwargs['extra'], cls=SetJSONEncoder)}
        return msg, kwargs


_LOG = logging.getLogger(__name__)
_LOG.addHandler(JournalHandler())
LOG = LogExtraAsJsonDataAdapter(_LOG, {})

The idea here is that Journalbeat sends those logs to Logstash where JSON_SD is JSON decoded and included into the log event.

RFE: provide service status querying

Are there any plans for this project to support querying service status from systemd? Or for that matter, controlling services via start/stop/restart requests (provided permissions are sufficient of course)?

For example, I'd like to be able to do something like the following:

from systemd import Service

svc = Service('my-cool-service')
status = svc.status()  # similar content to running 'systemctl status my-cool-service'
if svc.is_active():
    ... do stuff...
else:
    svc.start()

compiled error on centos 8

gcc (GCC) 8.3.1 20191121 (Red Hat 8.3.1-5)
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[stack@openstack devstack]$ gcc-c++ --version
-bash: gcc-c++: command not found
[stack@openstack devstack]$ c++ --version
c++ (GCC) 8.3.1 20191121 (Red Hat 8.3.1-5)
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[stack@openstack devstack]$ sudo pip install systemd-python
Collecting systemd-python
  Using cached systemd-python-234.tar.gz (53 kB)
Building wheels for collected packages: systemd-python
Building wheels for collected packages: systemd-python
  Building wheel for systemd-python (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: /usr/bin/python3.6 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-oqfbprfv/systemd-python/setup.py'"'"'; __file__='"'"'/tmp/pip-install-oqfbprfv/systemd-python/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-dbrwmi1t
       cwd: /tmp/pip-install-oqfbprfv/systemd-python/
  Complete output (32 lines):
  running bdist_wheel
  running build
  running build_py
  package init file 'systemd/test/__init__.py' not found (or not a regular file)
  creating build
  creating build/lib.linux-x86_64-3.6
  creating build/lib.linux-x86_64-3.6/systemd
  copying systemd/__init__.py -> build/lib.linux-x86_64-3.6/systemd
  copying systemd/journal.py -> build/lib.linux-x86_64-3.6/systemd
  copying systemd/daemon.py -> build/lib.linux-x86_64-3.6/systemd
  creating build/lib.linux-x86_64-3.6/systemd/test
  copying systemd/test/test_daemon.py -> build/lib.linux-x86_64-3.6/systemd/test
  copying systemd/test/test_journal.py -> build/lib.linux-x86_64-3.6/systemd/test
  copying systemd/test/test_login.py -> build/lib.linux-x86_64-3.6/systemd/test
  running build_ext
  building 'systemd/_journal' extension
  creating build/temp.linux-x86_64-3.6
  creating build/temp.linux-x86_64-3.6/systemd
  gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -DPACKAGE_VERSION="234" -DLIBSYSTEMD_VERSION=239 (239-41.el8_3) -I/usr/include/python3.6m -c systemd/_journal.c -o build/temp.linux-x86_64-3.6/systemd/_journal.o -Werror=implicit-function-declaration
  gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -DPACKAGE_VERSION="234" -DLIBSYSTEMD_VERSION=239 (239-41.el8_3) -I/usr/include/python3.6m -c systemd/pyutil.c -o build/temp.linux-x86_64-3.6/systemd/pyutil.o -Werror=implicit-function-declaration
  gcc -pthread -shared -Wl,-z,relro -Wl,-z,now -g -Wl,-z,relro -Wl,-z,now -g build/temp.linux-x86_64-3.6/systemd/_journal.o build/temp.linux-x86_64-3.6/systemd/pyutil.o -L/usr/lib64 -lsystemd -lpython3.6m -o build/lib.linux-x86_64-3.6/systemd/_journal.cpython-36m-x86_64-linux-gnu.so
  building 'systemd/_reader' extension
  gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -DPACKAGE_VERSION="234" -DLIBSYSTEMD_VERSION=239 (239-41.el8_3) -I/usr/include/python3.6m -c systemd/_reader.c -o build/temp.linux-x86_64-3.6/systemd/_reader.o -Werror=implicit-function-declaration
  <command-line>: error: missing binary operator before token "("
  systemd/_reader.c:41:5: note: in expansion of macro โ€˜LIBSYSTEMD_VERSIONโ€™
   #if LIBSYSTEMD_VERSION >= 229
       ^~~~~~~~~~~~~~~~~~
  <command-line>: error: missing binary operator before token "("
  systemd/_reader.c:47:5: note: in expansion of macro โ€˜LIBSYSTEMD_VERSIONโ€™
   #if LIBSYSTEMD_VERSION >= 230
       ^~~~~~~~~~~~~~~~~~
  error: command 'gcc' failed with exit status 1
  ----------------------------------------
  ERROR: Failed building wheel for systemd-python
  Running setup.py clean for systemd-python
Failed to build systemd-python
Installing collected packages: systemd-python
    Running setup.py install for systemd-python ... error
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3.6 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-oqfbprfv/systemd-python/setup.py'"'"'; __file__='"'"'/tmp/pip-install-oqfbprfv/systemd-python/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-ml2axpnp/install-record.txt --single-version-externally-managed --compile --install-headers /usr/local/include/python3.6m/systemd-python
         cwd: /tmp/pip-install-oqfbprfv/systemd-python/
    Complete output (32 lines):
    running install
    running build
    running build_py
    package init file 'systemd/test/__init__.py' not found (or not a regular file)
    creating build
    creating build/lib.linux-x86_64-3.6
    creating build/lib.linux-x86_64-3.6/systemd
    copying systemd/__init__.py -> build/lib.linux-x86_64-3.6/systemd
    copying systemd/journal.py -> build/lib.linux-x86_64-3.6/systemd
    copying systemd/daemon.py -> build/lib.linux-x86_64-3.6/systemd
    creating build/lib.linux-x86_64-3.6/systemd/test
    copying systemd/test/test_daemon.py -> build/lib.linux-x86_64-3.6/systemd/test
    copying systemd/test/test_journal.py -> build/lib.linux-x86_64-3.6/systemd/test
    copying systemd/test/test_login.py -> build/lib.linux-x86_64-3.6/systemd/test
    running build_ext
    building 'systemd/_journal' extension
    creating build/temp.linux-x86_64-3.6
    creating build/temp.linux-x86_64-3.6/systemd
    gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -DPACKAGE_VERSION="234" -DLIBSYSTEMD_VERSION=239 (239-41.el8_3) -I/usr/include/python3.6m -c systemd/_journal.c -o build/temp.linux-x86_64-3.6/systemd/_journal.o -Werror=implicit-function-declaration
    gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -DPACKAGE_VERSION="234" -DLIBSYSTEMD_VERSION=239 (239-41.el8_3) -I/usr/include/python3.6m -c systemd/pyutil.c -o build/temp.linux-x86_64-3.6/systemd/pyutil.o -Werror=implicit-function-declaration
    gcc -pthread -shared -Wl,-z,relro -Wl,-z,now -g -Wl,-z,relro -Wl,-z,now -g build/temp.linux-x86_64-3.6/systemd/_journal.o build/temp.linux-x86_64-3.6/systemd/pyutil.o -L/usr/lib64 -lsystemd -lpython3.6m -o build/lib.linux-x86_64-3.6/systemd/_journal.cpython-36m-x86_64-linux-gnu.so
    building 'systemd/_reader' extension
    gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -DPACKAGE_VERSION="234" -DLIBSYSTEMD_VERSION=239 (239-41.el8_3) -I/usr/include/python3.6m -c systemd/_reader.c -o build/temp.linux-x86_64-3.6/systemd/_reader.o -Werror=implicit-function-declaration
    <command-line>: error: missing binary operator before token "("
    systemd/_reader.c:41:5: note: in expansion of macro โ€˜LIBSYSTEMD_VERSIONโ€™
     #if LIBSYSTEMD_VERSION >= 229
         ^~~~~~~~~~~~~~~~~~
    <command-line>: error: missing binary operator before token "("
    systemd/_reader.c:47:5: note: in expansion of macro โ€˜LIBSYSTEMD_VERSIONโ€™
     #if LIBSYSTEMD_VERSION >= 230
         ^~~~~~~~~~~~~~~~~~
    error: command 'gcc' failed with exit status 1
    ----------------------------------------
ERROR: Command errored out with exit status 1: /usr/bin/python3.6 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-oqfbprfv/systemd-python/setup.py'"'"'; __file__='"'"'/tmp/pip-install-oqfbprfv/systemd-python/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-ml2axpnp/install-record.txt --single-version-externally-managed --compile --install-headers /usr/local/include/python3.6m/systemd-python Check the logs for full command output.
WARNING: You are using pip version 20.2.4; however, version 20.3.1 is available.
You should consider upgrading via the '/usr/bin/python3.6 -m pip install --upgrade pip' command.
[stack@openstack devstack]$ cat /etc/centos-release
CentOS Linux release 8.3.2011
[stack@openstack devstack]$```

test_notify_socket fails when ran from within nspawn

mock uses nspawn and build fails on

____________________________ test_notify_no_socket _____________________________

    def test_notify_no_socket():
>       assert notify('READY=1') is False
E       OSError: [Errno 13] Permission denied

systemd/test/test_daemon.py:260: OSError

With @torsava we were not able to debug it, so filing report here.. =(

Project status

Sorry for this fake issue.

But I need to know (and maybe I'm not alone) if this project is still maintained, or not. It can also be in standby. We just don't know what's happening, because there are some opened pull requests for more than one year without any comments.

Once again, sorry for pinging @keszybz but you seems to be the last active contributor to this, so maybe you can answer this.

poll and fileno()

I have a loop which seems to work for some time but then after a number of messages it starts to fall through even there is no data available on the Reader.

Basically,

j = journal.Reader()
j.this_boot()
poller = select.poll()
poller.register(j.fileno())
while True:
    poller.poll()  # returns within 1E-6 seconds
    print(j.get_next())  # prints out {}

Is this some fundamental use error on my side? The poller object should only return when the journal endpoint has some data to be read?

I have systemd-python version:

In [6]: systemd.journal.__version__
Out[6]: '234'

Administrative operation with python binding

Hello there,

How can I do the administrative operations with this binding? For instance, logrotate, or other things that journalctl can do like vacuum-size or vacuum-time?

Thanks

Cannot install systemd module via pip or apt due to compile errors or missing dependencies?

Cannot install systemd module via pip or apt due to compile errors or missing dependencies?

pip install fails when gcc compile fails...

pip3 install systemd
Collecting systemd
Using cached https://files.pythonhosted.org/packages/d4/c2/2195b049effd866b5d26926e672be83fc6f3263aa71ea0639e8eab44851e/systemd-0.16.1.tar.gz
Building wheels for collected packages: systemd
Running setup.py bdist_wheel for systemd ... error
Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;file='/tmp/pip-build-5atcutw4/systemd/setup.py';f=getattr(tokenize, 'open', open)(file);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, file, 'exec'))" bdist_wheel -d /tmp/tmpbbf8vpxjpip-wheel- --python-tag cp35:
/usr/lib/python3.5/distutils/dist.py:261: UserWarning: Unknown distribution option: 'build_requires'
warnings.warn(msg)
running bdist_wheel
running build
running build_py
creating build
creating build/lib.linux-armv7l-3.5
creating build/lib.linux-armv7l-3.5/systemd
copying systemd/journal.py -> build/lib.linux-armv7l-3.5/systemd
copying systemd/init.py -> build/lib.linux-armv7l-3.5/systemd
copying systemd/daemon.py -> build/lib.linux-armv7l-3.5/systemd
running build_ext
building 'systemd._daemon' extension
creating build/temp.linux-armv7l-3.5
creating build/temp.linux-armv7l-3.5/systemd
arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fdebug-prefix-map=/build/python3.5-6waWnr/python3.5-3.5.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.5m -c systemd/_daemon.c -o build/temp.linux-armv7l-3.5/systemd/_daemon.o
systemd/_daemon.c:539:31: fatal error: systemd/sd-daemon.h: No such file or directory
#include <systemd/sd-daemon.h>
^
compilation terminated.
error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1


Failed building wheel for systemd
Running setup.py clean for systemd
Failed to build systemd
Installing collected packages: systemd
Running setup.py install for systemd ... error
Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;file='/tmp/pip-build-5atcutw4/systemd/setup.py';f=getattr(tokenize, 'open', open)(file);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, file, 'exec'))" install --record /tmp/pip-cwvu2w6c-record/install-record.txt --single-version-externally-managed --compile:
/usr/lib/python3.5/distutils/dist.py:261: UserWarning: Unknown distribution option: 'build_requires'
warnings.warn(msg)
running install
running build
running build_py
creating build
creating build/lib.linux-armv7l-3.5
creating build/lib.linux-armv7l-3.5/systemd
copying systemd/journal.py -> build/lib.linux-armv7l-3.5/systemd
copying systemd/init.py -> build/lib.linux-armv7l-3.5/systemd
copying systemd/daemon.py -> build/lib.linux-armv7l-3.5/systemd
running build_ext
building 'systemd._daemon' extension
creating build/temp.linux-armv7l-3.5
creating build/temp.linux-armv7l-3.5/systemd
arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fdebug-prefix-map=/build/python3.5-6waWnr/python3.5-3.5.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.5m -c systemd/_daemon.c -o build/temp.linux-armv7l-3.5/systemd/_daemon.o
systemd/_daemon.c:539:31: fatal error: systemd/sd-daemon.h: No such file or directory
#include <systemd/sd-daemon.h>
^
compilation terminated.
error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1

----------------------------------------

Command "/usr/bin/python3 -u -c "import setuptools, tokenize;file='/tmp/pip-build-5atcutw4/systemd/setup.py';f=getattr(tokenize, 'open', open)(file);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, file, 'exec'))" install --record /tmp/pip-cwvu2w6c-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-5atcutw4/systemd/

And via APT...

apt install python-systemd
Reading package lists... Done
Building dependency tree
Reading state information... Done
python-systemd is already the newest version (233-1).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
1 not fully installed or removed.
After this operation, 0 B of additional disk space will be used.
Do you want to continue? [Y/n] y
Setting up python-systemd (233-1) ...
Traceback (most recent call last):
File "/usr/bin/pycompile", line 35, in
from debpython.version import SUPPORTED, debsorted, vrepr,
File "/usr/share/python/debpython/version.py", line 24, in
from ConfigParser import SafeConfigParser
ImportError: No module named 'ConfigParser'
dpkg: error processing package python-systemd (--configure):
subprocess installed post-installation script returned error exit status 1
Errors were encountered while processing:
python-systemd
E: Sub-process /usr/bin/dpkg returned an error code (1)

Logs between two dates

Hello there,

I want to get logs only between two specific dates, how should I achieve that?

Thanks

Please hook up api doc generation in the build system

The sphinx-based API documentation in systemd/docs/ is currently not hooked up in the build process and one needs to run spinx manually. It would be nice if the API documentation could be generated as part of the build process or at least document how one needs to run sphinx to generate the documentation. So far I failed to do that, because spinx did not find the systemd python modules.

compile error on Arch Linux

Can't run the following within a venv:

pip install systemd

It fails with this output

Collecting systemd
  Using cached systemd-0.16.1.tar.gz (173 kB)
Using legacy 'setup.py install' for systemd, since package 'wheel' is not installed.
Installing collected packages: systemd
    Running setup.py install for systemd: started
    Running setup.py install for systemd: finished with status 'error'
    ERROR: Command errored out with exit status 1:
     command: /home/jeanluc/Code/reddit-scheduler/.venv/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-rs318epm/systemd/setup.py'"'"'; __file__='"'"'/tmp/pip-install-rs318epm/systemd/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-pg_yt4_e/install-record.txt --single-version-externally-managed --compile --install-headers /home/jeanluc/Code/reddit-scheduler/.venv/include/site/python3.9/systemd
         cwd: /tmp/pip-install-rs318epm/systemd/
    Complete output (395 lines):
    /usr/lib/python3.9/distutils/dist.py:274: UserWarning: Unknown distribution option: 'build_requires'
      warnings.warn(msg)
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-3.9
    creating build/lib.linux-x86_64-3.9/systemd
    copying systemd/daemon.py -> build/lib.linux-x86_64-3.9/systemd
    copying systemd/__init__.py -> build/lib.linux-x86_64-3.9/systemd
    copying systemd/journal.py -> build/lib.linux-x86_64-3.9/systemd
    running build_ext
    building 'systemd._daemon' extension
    creating build/temp.linux-x86_64-3.9
    creating build/temp.linux-x86_64-3.9/systemd
    /usr/bin/clang -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fno-semantic-interposition -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -I/home/jeanluc/Code/reddit-scheduler/.venv/include -I/usr/include/python3.9 -c systemd/_daemon.c -o build/temp.linux-x86_64-3.9/systemd/_daemon.o
    cython_utility:524:22: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                        (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
                         ^
    /usr/include/python3.9/cpython/unicodeobject.h:261:7: note: expanded from macro 'PyUnicode_GET_SIZE'
          PyUnicode_WSTR_LENGTH(op) :                    \
          ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:524:22: warning: 'PyUnicode_AsUnicode' is deprecated [-Wdeprecated-declarations]
                        (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
                         ^
    /usr/include/python3.9/cpython/unicodeobject.h:262:14: note: expanded from macro 'PyUnicode_GET_SIZE'
          ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\
                 ^
    /usr/include/python3.9/cpython/unicodeobject.h:580:1: note: 'PyUnicode_AsUnicode' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode(
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:524:22: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                        (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
                         ^
    /usr/include/python3.9/cpython/unicodeobject.h:264:8: note: expanded from macro 'PyUnicode_GET_SIZE'
           PyUnicode_WSTR_LENGTH(op)))
           ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:524:52: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                        (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
                                                       ^
    /usr/include/python3.9/cpython/unicodeobject.h:261:7: note: expanded from macro 'PyUnicode_GET_SIZE'
          PyUnicode_WSTR_LENGTH(op) :                    \
          ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:524:52: warning: 'PyUnicode_AsUnicode' is deprecated [-Wdeprecated-declarations]
                        (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
                                                       ^
    /usr/include/python3.9/cpython/unicodeobject.h:262:14: note: expanded from macro 'PyUnicode_GET_SIZE'
          ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\
                 ^
    /usr/include/python3.9/cpython/unicodeobject.h:580:1: note: 'PyUnicode_AsUnicode' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode(
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:524:52: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                        (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
                                                       ^
    /usr/include/python3.9/cpython/unicodeobject.h:264:8: note: expanded from macro 'PyUnicode_GET_SIZE'
           PyUnicode_WSTR_LENGTH(op)))
           ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:540:26: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                            (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
                             ^
    /usr/include/python3.9/cpython/unicodeobject.h:261:7: note: expanded from macro 'PyUnicode_GET_SIZE'
          PyUnicode_WSTR_LENGTH(op) :                    \
          ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:540:26: warning: 'PyUnicode_AsUnicode' is deprecated [-Wdeprecated-declarations]
                            (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
                             ^
    /usr/include/python3.9/cpython/unicodeobject.h:262:14: note: expanded from macro 'PyUnicode_GET_SIZE'
          ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\
                 ^
    /usr/include/python3.9/cpython/unicodeobject.h:580:1: note: 'PyUnicode_AsUnicode' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode(
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:540:26: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                            (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
                             ^
    /usr/include/python3.9/cpython/unicodeobject.h:264:8: note: expanded from macro 'PyUnicode_GET_SIZE'
           PyUnicode_WSTR_LENGTH(op)))
           ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:540:59: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                            (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
                                                              ^
    /usr/include/python3.9/cpython/unicodeobject.h:261:7: note: expanded from macro 'PyUnicode_GET_SIZE'
          PyUnicode_WSTR_LENGTH(op) :                    \
          ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:540:59: warning: 'PyUnicode_AsUnicode' is deprecated [-Wdeprecated-declarations]
                            (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
                                                              ^
    /usr/include/python3.9/cpython/unicodeobject.h:262:14: note: expanded from macro 'PyUnicode_GET_SIZE'
          ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\
                 ^
    /usr/include/python3.9/cpython/unicodeobject.h:580:1: note: 'PyUnicode_AsUnicode' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode(
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:540:59: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                            (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
                                                              ^
    /usr/include/python3.9/cpython/unicodeobject.h:264:8: note: expanded from macro 'PyUnicode_GET_SIZE'
           PyUnicode_WSTR_LENGTH(op)))
           ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    12 warnings generated.
    gcc -pthread -shared -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fno-semantic-interposition -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now build/temp.linux-x86_64-3.9/systemd/_daemon.o -L/usr/lib -lsystemd -o build/lib.linux-x86_64-3.9/systemd/_daemon.cpython-39-x86_64-linux-gnu.so
    building 'systemd._journal' extension
    /usr/bin/clang -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fno-semantic-interposition -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -I/home/jeanluc/Code/reddit-scheduler/.venv/include -I/usr/include/python3.9 -c systemd/_journal.c -o build/temp.linux-x86_64-3.9/systemd/_journal.o -DSYSLOG_NAMES=1
    cython_utility:58:16: warning: 'PyUnicode_FromUnicode' is deprecated [-Wdeprecated-declarations]
            return PyUnicode_FromUnicode(NULL, 0);
                   ^
    /usr/include/python3.9/cpython/unicodeobject.h:551:1: note: 'PyUnicode_FromUnicode' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_FromUnicode(
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    1 warning generated.
    gcc -pthread -shared -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fno-semantic-interposition -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now build/temp.linux-x86_64-3.9/systemd/_journal.o -L/usr/lib -lsystemd -o build/lib.linux-x86_64-3.9/systemd/_journal.cpython-39-x86_64-linux-gnu.so
    building 'systemd.reader' extension
    /usr/bin/clang -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fno-semantic-interposition -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -I/home/jeanluc/Code/reddit-scheduler/.venv/include -I/usr/include/python3.9 -c systemd/reader.c -o build/temp.linux-x86_64-3.9/systemd/reader.o -DSYSLOG_NAMES=1
    systemd/reader.pyx:271:94: warning: passing 'char **' to parameter of type 'const char **' discards qualifiers in nested pointer types [-Wincompatible-pointer-types-discards-qualifiers]
                __pyx_t_2 = __Pyx_PyInt_From_int(sd_journal_open_files((&__pyx_v_self->context), __pyx_v_paths, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 271, __pyx_L12_error)
                                                                                                 ^~~~~~~~~~~~~
    /usr/include/systemd/sd-journal.h:89:58: note: passing argument to parameter 'paths' here
    int sd_journal_open_files(sd_journal **ret, const char **paths, int flags);
                                                             ^
    (tree fragment):161:39: error: no member named 'tp_print' in 'struct _typeobject'
      __pyx_type_7systemd_6reader_Matcher.tp_print = 0;
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
    (tree fragment):166:41: error: no member named 'tp_print' in 'struct _typeobject'
      __pyx_type_7systemd_6reader_Operation.tp_print = 0;
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
    (tree fragment):174:44: error: no member named 'tp_print' in 'struct _typeobject'
      __pyx_type_7systemd_6reader_JournalEntry.tp_print = 0;
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
    (tree fragment):182:45: error: no member named 'tp_print' in 'struct _typeobject'
      __pyx_type_7systemd_6reader_JournalReader.tp_print = 0;
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
    (tree fragment):188:57: error: no member named 'tp_print' in 'struct _typeobject'
      __pyx_type_7systemd_6reader___pyx_scope_struct___lock.tp_print = 0;
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
    (tree fragment):191:57: error: no member named 'tp_print' in 'struct _typeobject'
      __pyx_scope_struct____Pyx_CFunc_str____object___to_py.tp_print = 0;
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
    cython_utility:163:22: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                        (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
                         ^
    /usr/include/python3.9/cpython/unicodeobject.h:261:7: note: expanded from macro 'PyUnicode_GET_SIZE'
          PyUnicode_WSTR_LENGTH(op) :                    \
          ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:163:22: warning: 'PyUnicode_AsUnicode' is deprecated [-Wdeprecated-declarations]
                        (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
                         ^
    /usr/include/python3.9/cpython/unicodeobject.h:262:14: note: expanded from macro 'PyUnicode_GET_SIZE'
          ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\
                 ^
    /usr/include/python3.9/cpython/unicodeobject.h:580:1: note: 'PyUnicode_AsUnicode' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode(
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:163:22: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                        (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
                         ^
    /usr/include/python3.9/cpython/unicodeobject.h:264:8: note: expanded from macro 'PyUnicode_GET_SIZE'
           PyUnicode_WSTR_LENGTH(op)))
           ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:163:52: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                        (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
                                                       ^
    /usr/include/python3.9/cpython/unicodeobject.h:261:7: note: expanded from macro 'PyUnicode_GET_SIZE'
          PyUnicode_WSTR_LENGTH(op) :                    \
          ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:163:52: warning: 'PyUnicode_AsUnicode' is deprecated [-Wdeprecated-declarations]
                        (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
                                                       ^
    /usr/include/python3.9/cpython/unicodeobject.h:262:14: note: expanded from macro 'PyUnicode_GET_SIZE'
          ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\
                 ^
    /usr/include/python3.9/cpython/unicodeobject.h:580:1: note: 'PyUnicode_AsUnicode' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode(
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:163:52: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                        (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
                                                       ^
    /usr/include/python3.9/cpython/unicodeobject.h:264:8: note: expanded from macro 'PyUnicode_GET_SIZE'
           PyUnicode_WSTR_LENGTH(op)))
           ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:179:26: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                            (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
                             ^
    /usr/include/python3.9/cpython/unicodeobject.h:261:7: note: expanded from macro 'PyUnicode_GET_SIZE'
          PyUnicode_WSTR_LENGTH(op) :                    \
          ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:179:26: warning: 'PyUnicode_AsUnicode' is deprecated [-Wdeprecated-declarations]
                            (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
                             ^
    /usr/include/python3.9/cpython/unicodeobject.h:262:14: note: expanded from macro 'PyUnicode_GET_SIZE'
          ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\
                 ^
    /usr/include/python3.9/cpython/unicodeobject.h:580:1: note: 'PyUnicode_AsUnicode' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode(
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:179:26: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                            (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
                             ^
    /usr/include/python3.9/cpython/unicodeobject.h:264:8: note: expanded from macro 'PyUnicode_GET_SIZE'
           PyUnicode_WSTR_LENGTH(op)))
           ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:179:59: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                            (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
                                                              ^
    /usr/include/python3.9/cpython/unicodeobject.h:261:7: note: expanded from macro 'PyUnicode_GET_SIZE'
          PyUnicode_WSTR_LENGTH(op) :                    \
          ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:179:59: warning: 'PyUnicode_AsUnicode' is deprecated [-Wdeprecated-declarations]
                            (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
                                                              ^
    /usr/include/python3.9/cpython/unicodeobject.h:262:14: note: expanded from macro 'PyUnicode_GET_SIZE'
          ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\
                 ^
    /usr/include/python3.9/cpython/unicodeobject.h:580:1: note: 'PyUnicode_AsUnicode' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode(
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    cython_utility:179:59: warning: '_PyUnicode_get_wstr_length' is deprecated [-Wdeprecated-declarations]
                            (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
                                                              ^
    /usr/include/python3.9/cpython/unicodeobject.h:264:8: note: expanded from macro 'PyUnicode_GET_SIZE'
           PyUnicode_WSTR_LENGTH(op)))
           ^
    /usr/include/python3.9/cpython/unicodeobject.h:451:35: note: expanded from macro 'PyUnicode_WSTR_LENGTH'
    #define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op)
                                      ^
    /usr/include/python3.9/cpython/unicodeobject.h:445:1: note: '_PyUnicode_get_wstr_length' has been explicitly marked deprecated here
    Py_DEPRECATED(3.3)
    ^
    /usr/include/python3.9/pyport.h:508:54: note: expanded from macro 'Py_DEPRECATED'
    #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                         ^
    13 warnings and 6 errors generated.
    error: command '/usr/bin/clang' failed with exit code 1
    ----------------------------------------
ERROR: Command errored out with exit status 1: /home/jeanluc/Code/reddit-scheduler/.venv/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-rs318epm/systemd/setup.py'"'"'; __file__='"'"'/tmp/pip-install-rs318epm/systemd/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-pg_yt4_e/install-record.txt --single-version-externally-managed --compile --install-headers /home/jeanluc/Code/reddit-scheduler/.venv/include/site/python3.9/systemd Check the logs for full command output.
WARNING: You are using pip version 20.2.3; however, version 21.0.1 is available.
You should consider upgrading via the '/home/jeanluc/Code/reddit-scheduler/.venv/bin/python -m pip install --upgrade pip' command.

The important section seems to be:

    /usr/bin/clang -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fno-semantic-interposition -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fPIC -I/home/jeanluc/Code/reddit-scheduler/.venv/include -I/usr/include/python3.9 -c systemd/reader.c -o build/temp.linux-x86_64-3.9/systemd/reader.o -DSYSLOG_NAMES=1
    systemd/reader.pyx:271:94: warning: passing 'char **' to parameter of type 'const char **' discards qualifiers in nested pointer types [-Wincompatible-pointer-types-discards-qualifiers]
                __pyx_t_2 = __Pyx_PyInt_From_int(sd_journal_open_files((&__pyx_v_self->context), __pyx_v_paths, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 271, __pyx_L12_error)
                                                                                                 ^~~~~~~~~~~~~
    /usr/include/systemd/sd-journal.h:89:58: note: passing argument to parameter 'paths' here
    int sd_journal_open_files(sd_journal **ret, const char **paths, int flags);
                                                             ^
    (tree fragment):161:39: error: no member named 'tp_print' in 'struct _typeobject'
      __pyx_type_7systemd_6reader_Matcher.tp_print = 0;
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
    (tree fragment):166:41: error: no member named 'tp_print' in 'struct _typeobject'
      __pyx_type_7systemd_6reader_Operation.tp_print = 0;
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
    (tree fragment):174:44: error: no member named 'tp_print' in 'struct _typeobject'
      __pyx_type_7systemd_6reader_JournalEntry.tp_print = 0;
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
    (tree fragment):182:45: error: no member named 'tp_print' in 'struct _typeobject'
      __pyx_type_7systemd_6reader_JournalReader.tp_print = 0;
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
    (tree fragment):188:57: error: no member named 'tp_print' in 'struct _typeobject'
      __pyx_type_7systemd_6reader___pyx_scope_struct___lock.tp_print = 0;
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
    (tree fragment):191:57: error: no member named 'tp_print' in 'struct _typeobject'
      __pyx_scope_struct____Pyx_CFunc_str____object___to_py.tp_print = 0;

Some info:

$ pip --version
pip 20.2.3 from [....] (python 3.9)
$ uname -a 
Linux [...] 5.11.11-arch1-1 [...] x86_64 GNU/Linux

Document compatibility with systemd versions

It would be very handy to have some documentation about which systemd versions a release of this library is known to work against.

My story: I am currently using systemd 233 with python-systemd 234 (because I need some of the improvements that have been added to JournalHandler in 234). It seems to work okay, but it worries me, because the nature of the python-systemd version numbering scheme suggests that perhaps it is only meant to be used with the matching version of systemd.

Version 233 test-issues while building for openSUSE Leap 42.2

On openSUSE's Build-Environment the following test-error occurs:

The systemd version is "228"

[    3s] =================================== FAILURES ===================================
[    3s] _______________________ [doctest] systemd.journal.stream _______________________
[    3s] 450 Return a file object wrapping a stream to journal.
[    3s] 451 
[    3s] 452     Log messages written to this file as simple newline sepearted text strings
[    3s] 453     are written to the journal.
[    3s] 454 
[    3s] 455     The file will be line buffered, so messages are actually sent after a
[    3s] 456     newline character is written.
[    3s] 457 
[    3s] 458     >>> from systemd import journal
[    3s] 459     >>> stream = journal.stream('myapp')
[    3s] UNEXPECTED EXCEPTION: IOError(2, 'No such file or directory')
[    3s] Traceback (most recent call last):
[    3s] 
[    3s]   File "/usr/lib64/python2.7/doctest.py", line 1315, in __run
[    3s]     compileflags, 1) in test.globs
[    3s] 
[    3s]   File "<doctest systemd.journal.stream[1]>", line 1, in <module>
[    3s] 
[    3s]   File "/home/abuild/rpmbuild/BUILD/python-systemd-233/build/lib.linux-x86_64-2.7/systemd/journal.py", line 489, in stream
[    3s]     fd = stream_fd(identifier, priority, level_prefix)
[    3s] 
[    3s] IOError: [Errno 2] No such file or directory
[    3s] 
[    3s] /home/abuild/rpmbuild/BUILD/python-systemd-233/build/lib.linux-x86_64-2.7/systemd/journal.py:459: UnexpectedException

Log to a specific journal namespace

Hello there,

Recently systemd guys added the namespace feature, I want to log to a specific journal namespace inside my Python code, How can I achieve this behaviour? Can I do this without waiting for the future updates by, like using the _NAMESPACE keyword variable? or any other way?

Thanks,
Bahram

journal.sendv() should be consistent about raising exceptions on arguments

>>> journal.__version__
'216'
>>> journal.sendv('GRAPH=graph')
>>> journal.sendv('MESSAGE=graph')

The first sendv silently fails, the second silently succeeds (I guess sendv won't succeed unless the MESSAGE field is set.) Also...

>>> graph = 'graph\n'
>>> journal.sendv('GRAPH=%s' % graph)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 90] Message too long
>>> journal.sendv('GRAPH=%s' % graph, 'MESSAGE=actually, not too long')

In the above, IOError, Message too long, is raised. But, if I include the message field, it is logged to the journal.

Oct 29 11:47:24 localhost.localdomain python[20979]: actually, not too long
Oct 29 11:44:35 localhost.localdomain python[20979]: graph

So, some false assumptions are being made in error handling code which are pretty confusing too the user.

Note that in 219 the behavior is mostly the same, except that 'Message too long' become 'Invalid...'.

>>> journal.sendv('GRAPH=%s' % graph)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 22] Invalid argument

This is a good change, because it doesn't seem to be the length of the message that is the problem, just the fact that it contains a newline. But it is still wrong that the message is raised at all.

So, the two problems are:

  1. It should be possible to tell whether sendv has succeeded or failed, but it currently isn't.
  2. Error reporting should be better. Since a newline in a field is not actually a problem, the errors shown above should not be reported.

Create a new release?

Can you create a new release? We want to use this package, but need the functionality from #30. A release would be more stable than us just cloning from github. Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.