summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml56
-rw-r--r--.github/workflows/install.yml81
-rw-r--r--Makefile8
-rw-r--r--NEWS22
-rw-r--r--README.md142
-rw-r--r--docs/id128.rst14
-rw-r--r--setup.py2
-rw-r--r--systemd/_reader.c2
-rw-r--r--systemd/id128-constants.h14
-rw-r--r--systemd/id128-defines.h14
-rw-r--r--systemd/journal.py6
-rw-r--r--systemd/test/test_journal.py12
12 files changed, 330 insertions, 43 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..93f1bb1
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,56 @@
+---
+# vi: ts=2 sw=2 et:
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+name: Build test
+on:
+ pull_request:
+ push:
+ branches:
+ - main
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ runs-on: ubuntu-20.04
+ concurrency:
+ group: ${{ github.workflow }}-${{ matrix.python }}-${{ github.ref }}
+ cancel-in-progress: true
+ strategy:
+ fail-fast: false
+ matrix:
+ python: [
+ "3.7",
+ "3.8",
+ "3.9",
+ "3.10",
+ "3.11.0-rc.1",
+ ]
+ name: Python ${{ matrix.python }}
+ steps:
+ - name: Repository checkout
+ uses: actions/checkout@v2
+
+ - name: Configure Python ${{ matrix.python }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python }}
+ architecture: x64
+
+ - name: Install dependencies
+ run: |
+ sudo apt -y update
+ sudo apt -y install gcc libsystemd-dev
+ python -m pip install pytest sphinx
+
+ - name: Build (Python ${{ matrix.python }})
+ run: |
+ set -x
+ make -j
+ make doc SPHINXOPTS="-W -v"
+
+ - name: Test (Python ${{ matrix.python }})
+ run: |
+ make check
diff --git a/.github/workflows/install.yml b/.github/workflows/install.yml
new file mode 100644
index 0000000..6a8cc39
--- /dev/null
+++ b/.github/workflows/install.yml
@@ -0,0 +1,81 @@
+---
+# vi: ts=2 sw=2 et:
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+name: Install test
+on:
+ pull_request:
+ push:
+ branches:
+ - main
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ concurrency:
+ group: ${{ github.workflow }}-${{ matrix.container }}-${{ github.ref }}
+ cancel-in-progress: true
+ strategy:
+ fail-fast: false
+ matrix:
+ container: [
+ "archlinux:latest",
+ "debian:testing",
+ "quay.io/centos/centos:stream8",
+ "quay.io/fedora/fedora:rawhide",
+ "ubuntu:focal",
+ ]
+ container:
+ image: ${{ matrix.container }}
+ name: ${{ matrix.container }}
+ steps:
+ - name: Repository checkout
+ uses: actions/checkout@v2
+
+ - name: Install dependencies
+ shell: bash
+ run: |
+ DIST_ID="$(sed -nr 's/^ID="?(\w+)"?/\1/p' /etc/os-release)"
+ echo "Distribution ID: $DIST_ID"
+
+ DEPS_COMMON=(
+ gcc
+ git
+ pkg-config
+ python3
+ systemd
+ )
+
+ case "$DIST_ID" in
+ arch)
+ pacman --noconfirm -Sy "${DEPS_COMMON[@]}" systemd-libs
+ python3 -m ensurepip
+ ;;
+ centos|fedora)
+ dnf -y install "${DEPS_COMMON[@]}" systemd-devel python3-devel python3-pip
+ ;;
+ ubuntu|debian)
+ apt -y update
+ DEBIAN_FRONTEND=noninteractive apt -y install "${DEPS_COMMON[@]}" libsystemd-dev python3-dev python3-pip
+ ;;
+ *)
+ echo >&2 "Invalid distribution ID: $DISTRO_ID"
+ exit 1
+ esac
+
+ python3 -m pip install pytest sphinx
+
+ - name: Build & install
+ shell: bash
+ run: |
+ set -x
+ python3 -m pip install -I -v .
+ # Avoid importing the systemd module from the git repository
+ cd /
+ python3 -c 'from systemd import journal; print(journal.__version__)'
+ # Initialize /etc/machine-id if it's empty to make the tests happy
+ [[ ! -s /etc/machine-id ]] && systemd-id128 new >/etc/machine-id
+ pytest -v --pyargs systemd
diff --git a/Makefile b/Makefile
index b7070df..02d357f 100644
--- a/Makefile
+++ b/Makefile
@@ -7,8 +7,10 @@ VERSION := $(shell $(PYTHON) setup.py --version)
TESTFLAGS = -v
define buildscript
-import sys,sysconfig
-print("build/lib.{}-{}.{}".format(sysconfig.get_platform(), *sys.version_info[:2]))
+import sys, sysconfig, setuptools
+sversion = int(setuptools.__version__.split(".")[0])
+end = sys.implementation.cache_tag if sversion >= 61 else "{}.{}".format(*sys.version_info[:2])
+print("build/lib.{}-{}".format(sysconfig.get_platform(), end))
endef
builddir := $(shell $(PYTHON) -c '$(buildscript)')
@@ -48,7 +50,7 @@ clean:
distclean: clean
rm -rf dist MANIFEST
-SPHINXOPTS = -D version=$(VERSION) -D release=$(VERSION)
+SPHINXOPTS += -D version=$(VERSION) -D release=$(VERSION)
sphinx-%: build
cd build && \
PYTHONPATH=../$(builddir) $(PYTHON) -m sphinx -b $* $(SPHINXOPTS) ../docs $*
diff --git a/NEWS b/NEWS
index 9cf35f4..17e3b82 100644
--- a/NEWS
+++ b/NEWS
@@ -2,11 +2,25 @@ Python wrappers for libsystemd API
CHANGES WITH 235:
- * Adapt the rename of systemd-activate to systemd-socket-activate
- performed in systemd 230
+ * Adapt the rename of systemd-activate to systemd-socket-activate
+ performed in systemd 230.
- * Support for the new sd_listen_fds_with_names added in systemd 227
- is added.
+ * Support for the new sd_listen_fds_with_names added in systemd 227
+ is added.
+
+ * Make the Reader PY_SSIZE_T_CLEAN for py3.10 compatibility.
+
+ * id128: update for systemd-243 compatibility and other fixes.
+
+ * C syntax modernization. A minimum of C99 is assumed.
+
+ * Fix seek_realtime to work with timezone aware date.
+
+ * journal: add namespace support.
+
+ * Memory leak fixes.
+
+ * Documentation and other fixes.
CHANGES WITH 234:
diff --git a/README.md b/README.md
index 2beb373..8c5c5bf 100644
--- a/README.md
+++ b/README.md
@@ -3,13 +3,13 @@ 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
+- `systemd.journal` supports sending of structured messages to the journal
and reading journal files,
-- systemd.daemon wraps parts of libsystemd useful for writing daemons
+- `systemd.daemon` wraps parts of `libsystemd` useful for writing daemons
and socket activation,
-- systemd.id128 provides functions for querying machine and boot identifiers
+- `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
+- `systemd.login` wraps parts of `libsystemd` used to query logged in users
and available seats and machines.
Installation
@@ -17,17 +17,22 @@ Installation
This module should be packaged for almost all Linux distributions. Use
-On Fedora/RHEL/CentOS
+On Fedora:
- dnf install python-systemd python3-systemd
+ dnf install python3-systemd
-On Debian/Ubuntu/Mint
+On Debian/Ubuntu/Mint:
- apt-get install python-systemd python3-systemd
+ apt update
+ apt install python3-systemd
-On openSUSE and SLE
+On openSUSE and SLE:
- zypper in python-systemd
+ zypper in python3-systemd
+
+On Arch:
+
+ pacman -Sy python-systemd
To build from source
--------------------
@@ -35,20 +40,20 @@ To build from source
On CentOS, RHEL, and Fedora with Python 2:
dnf install git python-pip gcc python-devel systemd-devel
- pip install git+https://github.com/systemd/python-systemd.git#egg=systemd
+ pip install 'git+https://github.com/systemd/python-systemd.git#egg=systemd-python'
On Fedora with Python 3:
dnf install git python3-pip gcc python3-devel systemd-devel
- pip3 install git+https://github.com/systemd/python-systemd.git#egg=systemd
+ pip3 install 'git+https://github.com/systemd/python-systemd.git#egg=systemd-python'
On Debian or Ubuntu with Python 2:
- apt-get install libsystemd-{journal,daemon,login,id128}-dev gcc python-dev pkg-config
+ apt install libsystemd-{journal,daemon,login,id128}-dev gcc python-dev pkg-config
On Debian or Ubuntu with Python 3:
- apt-get install libsystemd-{journal,daemon,login,id128}-dev gcc python3-dev pkg-config
+ apt install libsystemd-{journal,daemon,login,id128}-dev gcc python3-dev pkg-config
The project is also available on pypi as `systemd-python`.
@@ -62,7 +67,7 @@ Quick example:
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
+There is one required argument — the message, and additional fields
can be specified as keyword arguments. Following the journald API, all
names are uppercase.
@@ -76,35 +81,110 @@ The journald sendv call can also be accessed directly:
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](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html).
+
+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 % operator or .format() capabilities
- first.
- * 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.
+* 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()
+ capabilities or `%` 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())
+ logger.addHandler(journal.JournalHandler(SYSLOG_IDENTIFIER='custom_unit_name'))
logger.warning("Some message: %s", 'detail')
-libsytemd version compatibility
--------------------------------
+`libsystemd` version compatibility
+----------------------------------
-This module may be compiled against any version of libsystemd. At
+This module may be compiled against any version of `libsystemd`. At
compilation time, any functionality that is not available in that
-version of systemd 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.
+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
=============
diff --git a/docs/id128.rst b/docs/id128.rst
index 631652f..cd562d5 100644
--- a/docs/id128.rst
+++ b/docs/id128.rst
@@ -11,10 +11,13 @@
.. autoattribute:: systemd.id128.SD_MESSAGE_BOOTCHART
.. autoattribute:: systemd.id128.SD_MESSAGE_CONFIG_ERROR
.. autoattribute:: systemd.id128.SD_MESSAGE_COREDUMP
+ .. autoattribute:: systemd.id128.SD_MESSAGE_DEVICE_PATH_NOT_SUITABLE
.. autoattribute:: systemd.id128.SD_MESSAGE_DNSSEC_DOWNGRADE
.. autoattribute:: systemd.id128.SD_MESSAGE_DNSSEC_FAILURE
.. autoattribute:: systemd.id128.SD_MESSAGE_DNSSEC_TRUST_ANCHOR_REVOKED
+ .. autoattribute:: systemd.id128.SD_MESSAGE_FACTORY_RESET
.. autoattribute:: systemd.id128.SD_MESSAGE_FORWARD_SYSLOG_MISSED
+ .. autoattribute:: systemd.id128.SD_MESSAGE_HIBERNATE_KEY_LONG_PRESS
.. autoattribute:: systemd.id128.SD_MESSAGE_HIBERNATE_KEY
.. autoattribute:: systemd.id128.SD_MESSAGE_INVALID_CONFIGURATION
.. autoattribute:: systemd.id128.SD_MESSAGE_JOURNAL_DROPPED
@@ -26,8 +29,13 @@
.. autoattribute:: systemd.id128.SD_MESSAGE_LID_OPENED
.. autoattribute:: systemd.id128.SD_MESSAGE_MACHINE_START
.. autoattribute:: systemd.id128.SD_MESSAGE_MACHINE_STOP
+ .. autoattribute:: systemd.id128.SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE
+ .. autoattribute:: systemd.id128.SD_MESSAGE_NOBODY_USER_UNSUITABLE
.. autoattribute:: systemd.id128.SD_MESSAGE_OVERMOUNTING
+ .. autoattribute:: systemd.id128.SD_MESSAGE_POWER_KEY_LONG_PRESS
.. autoattribute:: systemd.id128.SD_MESSAGE_POWER_KEY
+ .. autoattribute:: systemd.id128.SD_MESSAGE_REBOOT_KEY_LONG_PRESS
+ .. autoattribute:: systemd.id128.SD_MESSAGE_REBOOT_KEY
.. autoattribute:: systemd.id128.SD_MESSAGE_SEAT_START
.. autoattribute:: systemd.id128.SD_MESSAGE_SEAT_STOP
.. autoattribute:: systemd.id128.SD_MESSAGE_SESSION_START
@@ -37,24 +45,30 @@
.. autoattribute:: systemd.id128.SD_MESSAGE_SLEEP_STOP
.. autoattribute:: systemd.id128.SD_MESSAGE_SPAWN_FAILED
.. autoattribute:: systemd.id128.SD_MESSAGE_STARTUP_FINISHED
+ .. autoattribute:: systemd.id128.SD_MESSAGE_SUSPEND_KEY_LONG_PRESS
.. autoattribute:: systemd.id128.SD_MESSAGE_SUSPEND_KEY
.. autoattribute:: systemd.id128.SD_MESSAGE_SYSTEM_DOCKED
+ .. autoattribute:: systemd.id128.SD_MESSAGE_SYSTEMD_UDEV_SETTLE_DEPRECATED
.. autoattribute:: systemd.id128.SD_MESSAGE_SYSTEM_UNDOCKED
.. autoattribute:: systemd.id128.SD_MESSAGE_TAINTED
.. autoattribute:: systemd.id128.SD_MESSAGE_TIME_CHANGE
+ .. autoattribute:: systemd.id128.SD_MESSAGE_TIME_SYNC
.. autoattribute:: systemd.id128.SD_MESSAGE_TIMEZONE_CHANGE
.. autoattribute:: systemd.id128.SD_MESSAGE_TRUNCATED_CORE
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_FAILED
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_FAILURE_RESULT
+ .. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_OOMD_KILL
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_OUT_OF_MEMORY
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_PROCESS_EXIT
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_RELOADED
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_RELOADING
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_RESOURCES
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_RESTART_SCHEDULED
+ .. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_SKIPPED
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STARTED
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STARTING
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STOPPED
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STOPPING
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_SUCCESS
+ .. autoattribute:: systemd.id128.SD_MESSAGE_UNSAFE_USER_NAME
.. autoattribute:: systemd.id128.SD_MESSAGE_USER_STARTUP_FINISHED
diff --git a/setup.py b/setup.py
index 099819b..fe9c03a 100644
--- a/setup.py
+++ b/setup.py
@@ -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):
diff --git a/systemd/_reader.c b/systemd/_reader.c
index fda8991..4e8f47f 100644
--- a/systemd/_reader.c
+++ b/systemd/_reader.c
@@ -960,7 +960,7 @@ PyDoc_STRVAR(Reader_wait__doc__,
"See :manpage:`sd_journal_wait(3)` for further discussion.");
static PyObject* Reader_wait(Reader *self, PyObject *args) {
int r;
- int64_t timeout;
+ int64_t timeout = -1;
if (!PyArg_ParseTuple(args, "|L:wait", &timeout))
return NULL;
diff --git a/systemd/id128-constants.h b/systemd/id128-constants.h
index b606705..a1d215c 100644
--- a/systemd/id128-constants.h
+++ b/systemd/id128-constants.h
@@ -2,10 +2,13 @@ add_id(m, "SD_MESSAGE_BACKTRACE", SD_MESSAGE_BACKTRACE) JOINER
add_id(m, "SD_MESSAGE_BOOTCHART", SD_MESSAGE_BOOTCHART) JOINER
add_id(m, "SD_MESSAGE_CONFIG_ERROR", SD_MESSAGE_CONFIG_ERROR) JOINER
add_id(m, "SD_MESSAGE_COREDUMP", SD_MESSAGE_COREDUMP) JOINER
+add_id(m, "SD_MESSAGE_DEVICE_PATH_NOT_SUITABLE", SD_MESSAGE_DEVICE_PATH_NOT_SUITABLE) JOINER
add_id(m, "SD_MESSAGE_DNSSEC_DOWNGRADE", SD_MESSAGE_DNSSEC_DOWNGRADE) JOINER
add_id(m, "SD_MESSAGE_DNSSEC_FAILURE", SD_MESSAGE_DNSSEC_FAILURE) JOINER
add_id(m, "SD_MESSAGE_DNSSEC_TRUST_ANCHOR_REVOKED", SD_MESSAGE_DNSSEC_TRUST_ANCHOR_REVOKED) JOINER
+add_id(m, "SD_MESSAGE_FACTORY_RESET", SD_MESSAGE_FACTORY_RESET) JOINER
add_id(m, "SD_MESSAGE_FORWARD_SYSLOG_MISSED", SD_MESSAGE_FORWARD_SYSLOG_MISSED) JOINER
+add_id(m, "SD_MESSAGE_HIBERNATE_KEY_LONG_PRESS", SD_MESSAGE_HIBERNATE_KEY_LONG_PRESS) JOINER
add_id(m, "SD_MESSAGE_HIBERNATE_KEY", SD_MESSAGE_HIBERNATE_KEY) JOINER
add_id(m, "SD_MESSAGE_INVALID_CONFIGURATION", SD_MESSAGE_INVALID_CONFIGURATION) JOINER
add_id(m, "SD_MESSAGE_JOURNAL_DROPPED", SD_MESSAGE_JOURNAL_DROPPED) JOINER
@@ -17,8 +20,13 @@ add_id(m, "SD_MESSAGE_LID_CLOSED", SD_MESSAGE_LID_CLOSED) JOINER
add_id(m, "SD_MESSAGE_LID_OPENED", SD_MESSAGE_LID_OPENED) JOINER
add_id(m, "SD_MESSAGE_MACHINE_START", SD_MESSAGE_MACHINE_START) JOINER
add_id(m, "SD_MESSAGE_MACHINE_STOP", SD_MESSAGE_MACHINE_STOP) JOINER
+add_id(m, "SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE", SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE) JOINER
+add_id(m, "SD_MESSAGE_NOBODY_USER_UNSUITABLE", SD_MESSAGE_NOBODY_USER_UNSUITABLE) JOINER
add_id(m, "SD_MESSAGE_OVERMOUNTING", SD_MESSAGE_OVERMOUNTING) JOINER
+add_id(m, "SD_MESSAGE_POWER_KEY_LONG_PRESS", SD_MESSAGE_POWER_KEY_LONG_PRESS) JOINER
add_id(m, "SD_MESSAGE_POWER_KEY", SD_MESSAGE_POWER_KEY) JOINER
+add_id(m, "SD_MESSAGE_REBOOT_KEY_LONG_PRESS", SD_MESSAGE_REBOOT_KEY_LONG_PRESS) JOINER
+add_id(m, "SD_MESSAGE_REBOOT_KEY", SD_MESSAGE_REBOOT_KEY) JOINER
add_id(m, "SD_MESSAGE_SEAT_START", SD_MESSAGE_SEAT_START) JOINER
add_id(m, "SD_MESSAGE_SEAT_STOP", SD_MESSAGE_SEAT_STOP) JOINER
add_id(m, "SD_MESSAGE_SESSION_START", SD_MESSAGE_SESSION_START) JOINER
@@ -28,24 +36,30 @@ add_id(m, "SD_MESSAGE_SLEEP_START", SD_MESSAGE_SLEEP_START) JOINER
add_id(m, "SD_MESSAGE_SLEEP_STOP", SD_MESSAGE_SLEEP_STOP) JOINER
add_id(m, "SD_MESSAGE_SPAWN_FAILED", SD_MESSAGE_SPAWN_FAILED) JOINER
add_id(m, "SD_MESSAGE_STARTUP_FINISHED", SD_MESSAGE_STARTUP_FINISHED) JOINER
+add_id(m, "SD_MESSAGE_SUSPEND_KEY_LONG_PRESS", SD_MESSAGE_SUSPEND_KEY_LONG_PRESS) JOINER
add_id(m, "SD_MESSAGE_SUSPEND_KEY", SD_MESSAGE_SUSPEND_KEY) JOINER
add_id(m, "SD_MESSAGE_SYSTEM_DOCKED", SD_MESSAGE_SYSTEM_DOCKED) JOINER
+add_id(m, "SD_MESSAGE_SYSTEMD_UDEV_SETTLE_DEPRECATED", SD_MESSAGE_SYSTEMD_UDEV_SETTLE_DEPRECATED) JOINER
add_id(m, "SD_MESSAGE_SYSTEM_UNDOCKED", SD_MESSAGE_SYSTEM_UNDOCKED) JOINER
add_id(m, "SD_MESSAGE_TAINTED", SD_MESSAGE_TAINTED) JOINER
add_id(m, "SD_MESSAGE_TIME_CHANGE", SD_MESSAGE_TIME_CHANGE) JOINER
+add_id(m, "SD_MESSAGE_TIME_SYNC", SD_MESSAGE_TIME_SYNC) JOINER
add_id(m, "SD_MESSAGE_TIMEZONE_CHANGE", SD_MESSAGE_TIMEZONE_CHANGE) JOINER
add_id(m, "SD_MESSAGE_TRUNCATED_CORE", SD_MESSAGE_TRUNCATED_CORE) JOINER
add_id(m, "SD_MESSAGE_UNIT_FAILED", SD_MESSAGE_UNIT_FAILED) JOINER
add_id(m, "SD_MESSAGE_UNIT_FAILURE_RESULT", SD_MESSAGE_UNIT_FAILURE_RESULT) JOINER
+add_id(m, "SD_MESSAGE_UNIT_OOMD_KILL", SD_MESSAGE_UNIT_OOMD_KILL) JOINER
add_id(m, "SD_MESSAGE_UNIT_OUT_OF_MEMORY", SD_MESSAGE_UNIT_OUT_OF_MEMORY) JOINER
add_id(m, "SD_MESSAGE_UNIT_PROCESS_EXIT", SD_MESSAGE_UNIT_PROCESS_EXIT) JOINER
add_id(m, "SD_MESSAGE_UNIT_RELOADED", SD_MESSAGE_UNIT_RELOADED) JOINER
add_id(m, "SD_MESSAGE_UNIT_RELOADING", SD_MESSAGE_UNIT_RELOADING) JOINER
add_id(m, "SD_MESSAGE_UNIT_RESOURCES", SD_MESSAGE_UNIT_RESOURCES) JOINER
add_id(m, "SD_MESSAGE_UNIT_RESTART_SCHEDULED", SD_MESSAGE_UNIT_RESTART_SCHEDULED) JOINER
+add_id(m, "SD_MESSAGE_UNIT_SKIPPED", SD_MESSAGE_UNIT_SKIPPED) JOINER
add_id(m, "SD_MESSAGE_UNIT_STARTED", SD_MESSAGE_UNIT_STARTED) JOINER
add_id(m, "SD_MESSAGE_UNIT_STARTING", SD_MESSAGE_UNIT_STARTING) JOINER
add_id(m, "SD_MESSAGE_UNIT_STOPPED", SD_MESSAGE_UNIT_STOPPED) JOINER
add_id(m, "SD_MESSAGE_UNIT_STOPPING", SD_MESSAGE_UNIT_STOPPING) JOINER
add_id(m, "SD_MESSAGE_UNIT_SUCCESS", SD_MESSAGE_UNIT_SUCCESS) JOINER
+add_id(m, "SD_MESSAGE_UNSAFE_USER_NAME", SD_MESSAGE_UNSAFE_USER_NAME) JOINER
add_id(m, "SD_MESSAGE_USER_STARTUP_FINISHED", SD_MESSAGE_USER_STARTUP_FINISHED) JOINER
diff --git a/systemd/id128-defines.h b/systemd/id128-defines.h
index 4d937cd..178de83 100644
--- a/systemd/id128-defines.h
+++ b/systemd/id128-defines.h
@@ -2,10 +2,13 @@
#define SD_MESSAGE_BOOTCHART SD_ID128_MAKE(9f,26,aa,56,2c,f4,40,c2,b1,6c,77,3d,04,79,b5,18)
#define SD_MESSAGE_CONFIG_ERROR SD_ID128_MAKE(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01)
#define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1)
+#define SD_MESSAGE_DEVICE_PATH_NOT_SUITABLE SD_ID128_MAKE(01,01,90,13,8f,49,4e,29,a0,ef,66,69,74,95,31,aa)
#define SD_MESSAGE_DNSSEC_DOWNGRADE SD_ID128_MAKE(36,db,2d,fa,5a,90,45,e1,bd,4a,f5,f9,3e,1c,f0,57)
#define SD_MESSAGE_DNSSEC_FAILURE SD_ID128_MAKE(16,75,d7,f1,72,17,40,98,b1,10,8b,f8,c7,dc,8f,5d)
#define SD_MESSAGE_DNSSEC_TRUST_ANCHOR_REVOKED SD_ID128_MAKE(4d,44,08,cf,d0,d1,44,85,91,84,d1,e6,5d,7c,8a,65)
+#define SD_MESSAGE_FACTORY_RESET SD_ID128_MAKE(c1,4a,af,76,ec,28,4a,5f,a1,f1,05,f8,8d,fb,06,1c)
#define SD_MESSAGE_FORWARD_SYSLOG_MISSED SD_ID128_MAKE(00,27,22,9c,a0,64,41,81,a7,6c,4e,92,45,8a,fa,2e)
+#define SD_MESSAGE_HIBERNATE_KEY_LONG_PRESS SD_ID128_MAKE(16,78,36,df,6f,7f,42,8e,98,14,72,27,b2,dc,89,45)
#define SD_MESSAGE_HIBERNATE_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73)
#define SD_MESSAGE_INVALID_CONFIGURATION SD_ID128_MAKE(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01)
#define SD_MESSAGE_JOURNAL_DROPPED SD_ID128_MAKE(a5,96,d6,fe,7b,fa,49,94,82,8e,72,30,9e,95,d6,1e)
@@ -17,8 +20,13 @@
#define SD_MESSAGE_LID_OPENED SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,6f)
#define SD_MESSAGE_MACHINE_START SD_ID128_MAKE(24,d8,d4,45,25,73,40,24,96,06,83,81,a6,31,2d,f2)
#define SD_MESSAGE_MACHINE_STOP SD_ID128_MAKE(58,43,2b,d3,ba,ce,47,7c,b5,14,b5,63,81,b8,a7,58)
+#define SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE SD_ID128_MAKE(1b,3b,b9,40,37,f0,4b,bf,81,02,8e,13,5a,12,d2,93)
+#define SD_MESSAGE_NOBODY_USER_UNSUITABLE SD_ID128_MAKE(b4,80,32,5f,9c,39,4a,7b,80,2c,23,1e,51,a2,75,2c)
#define SD_MESSAGE_OVERMOUNTING SD_ID128_MAKE(1d,ee,03,69,c7,fc,47,36,b7,09,9b,38,ec,b4,6e,e7)
+#define SD_MESSAGE_POWER_KEY_LONG_PRESS SD_ID128_MAKE(3e,01,17,10,1e,b2,43,c1,b9,a5,0d,b3,49,4a,b1,0b)
#define SD_MESSAGE_POWER_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71)
+#define SD_MESSAGE_REBOOT_KEY_LONG_PRESS SD_ID128_MAKE(f1,c5,9a,58,c9,d9,43,66,89,65,c3,37,ca,ec,59,75)
+#define SD_MESSAGE_REBOOT_KEY SD_ID128_MAKE(9f,a9,d2,c0,12,13,4e,c3,85,45,1f,fe,31,6f,97,d0)
#define SD_MESSAGE_SEAT_START SD_ID128_MAKE(fc,be,fc,5d,a2,3d,42,80,93,f9,7c,82,a9,29,0f,7b)
#define SD_MESSAGE_SEAT_STOP SD_ID128_MAKE(e7,85,2b,fe,46,78,4e,d0,ac,cd,e0,4b,c8,64,c2,d5)
#define SD_MESSAGE_SESSION_START SD_ID128_MAKE(8d,45,62,0c,1a,43,48,db,b1,74,10,da,57,c6,0c,66)
@@ -28,24 +36,30 @@
#define SD_MESSAGE_SLEEP_STOP SD_ID128_MAKE(88,11,e6,df,2a,8e,40,f5,8a,94,ce,a2,6f,8e,bf,14)
#define SD_MESSAGE_SPAWN_FAILED SD_ID128_MAKE(64,12,57,65,1c,1b,4e,c9,a8,62,4d,7a,40,a9,e1,e7)
#define SD_MESSAGE_STARTUP_FINISHED SD_ID128_MAKE(b0,7a,24,9c,d0,24,41,4a,82,dd,00,cd,18,13,78,ff)
+#define SD_MESSAGE_SUSPEND_KEY_LONG_PRESS SD_ID128_MAKE(bf,da,f6,d3,12,ab,40,07,bc,1f,e4,0a,15,df,78,e8)
#define SD_MESSAGE_SUSPEND_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72)
#define SD_MESSAGE_SYSTEM_DOCKED SD_ID128_MAKE(f5,f4,16,b8,62,07,4b,28,92,7a,48,c3,ba,7d,51,ff)
+#define SD_MESSAGE_SYSTEMD_UDEV_SETTLE_DEPRECATED SD_ID128_MAKE(1c,04,54,c1,bd,22,41,e0,ac,6f,ef,b4,bc,63,14,33)
#define SD_MESSAGE_SYSTEM_UNDOCKED SD_ID128_MAKE(51,e1,71,bd,58,52,48,56,81,10,14,4c,51,7c,ca,53)
#define SD_MESSAGE_TAINTED SD_ID128_MAKE(50,87,6a,9d,b0,0f,4c,40,bd,e1,a2,ad,38,1c,3a,1b)
#define SD_MESSAGE_TIME_CHANGE SD_ID128_MAKE(c7,a7,87,07,9b,35,4e,aa,a9,e7,7b,37,18,93,cd,27)
+#define SD_MESSAGE_TIME_SYNC SD_ID128_MAKE(7c,8a,41,f3,7b,76,49,41,a0,e1,78,0b,1b,e2,f0,37)
#define SD_MESSAGE_TIMEZONE_CHANGE SD_ID128_MAKE(45,f8,2f,4a,ef,7a,4b,bf,94,2c,e8,61,d1,f2,09,90)
#define SD_MESSAGE_TRUNCATED_CORE SD_ID128_MAKE(5a,ad,d8,e9,54,dc,4b,1a,8c,95,4d,63,fd,9e,11,37)
#define SD_MESSAGE_UNIT_FAILED SD_ID128_MAKE(be,02,cf,68,55,d2,42,8b,a4,0d,f7,e9,d0,22,f0,3d)
#define SD_MESSAGE_UNIT_FAILURE_RESULT SD_ID128_MAKE(d9,b3,73,ed,55,a6,4f,eb,82,42,e0,2d,be,79,a4,9c)
+#define SD_MESSAGE_UNIT_OOMD_KILL SD_ID128_MAKE(d9,89,61,1b,15,e4,4c,9d,bf,31,e3,c8,12,56,e4,ed)
#define SD_MESSAGE_UNIT_OUT_OF_MEMORY SD_ID128_MAKE(fe,6f,aa,94,e7,77,46,63,a0,da,52,71,78,91,d8,ef)
#define SD_MESSAGE_UNIT_PROCESS_EXIT SD_ID128_MAKE(98,e3,22,20,3f,7a,4e,d2,90,d0,9f,e0,3c,09,fe,15)
#define SD_MESSAGE_UNIT_RELOADED SD_ID128_MAKE(7b,05,eb,c6,68,38,42,22,ba,a8,88,11,79,cf,da,54)
#define SD_MESSAGE_UNIT_RELOADING SD_ID128_MAKE(d3,4d,03,7f,ff,18,47,e6,ae,66,9a,37,0e,69,47,25)
#define SD_MESSAGE_UNIT_RESOURCES SD_ID128_MAKE(ae,8f,7b,86,6b,03,47,b9,af,31,fe,1c,80,b1,27,c0)
#define SD_MESSAGE_UNIT_RESTART_SCHEDULED SD_ID128_MAKE(5e,b0,34,94,b6,58,48,70,a5,36,b3,37,29,08,09,b3)
+#define SD_MESSAGE_UNIT_SKIPPED SD_ID128_MAKE(0e,42,84,a0,ca,ca,4b,fc,81,c0,bb,67,86,97,26,73)
#define SD_MESSAGE_UNIT_STARTED SD_ID128_MAKE(39,f5,34,79,d3,a0,45,ac,8e,11,78,62,48,23,1f,bf)
#define SD_MESSAGE_UNIT_STARTING SD_ID128_MAKE(7d,49,58,e8,42,da,4a,75,8f,6c,1c,dc,7b,36,dc,c5)
#define SD_MESSAGE_UNIT_STOPPED SD_ID128_MAKE(9d,1a,aa,27,d6,01,40,bd,96,36,54,38,aa,d2,02,86)
#define SD_MESSAGE_UNIT_STOPPING SD_ID128_MAKE(de,5b,42,6a,63,be,47,a7,b6,ac,3e,aa,c8,2e,2f,6f)
#define SD_MESSAGE_UNIT_SUCCESS SD_ID128_MAKE(7a,d2,d1,89,f7,e9,4e,70,a3,8c,78,13,54,91,24,48)
+#define SD_MESSAGE_UNSAFE_USER_NAME SD_ID128_MAKE(b6,1f,da,c6,12,e9,4b,91,82,28,5b,99,88,43,06,1f)
#define SD_MESSAGE_USER_STARTUP_FINISHED SD_ID128_MAKE(ee,d0,0a,68,ff,d8,4e,31,88,21,05,fd,97,3a,bd,d1)
diff --git a/systemd/journal.py b/systemd/journal.py
index 1670134..b1f2fef 100644
--- a/systemd/journal.py
+++ b/systemd/journal.py
@@ -51,13 +51,13 @@ def _convert_monotonic(m):
def _convert_source_monotonic(s):
return _datetime.timedelta(microseconds=int(s))
+_LOCAL_TIMEZONE = _datetime.datetime.now().astimezone().tzinfo
def _convert_realtime(t):
- return _datetime.datetime.fromtimestamp(t / 1000000)
-
+ return _datetime.datetime.fromtimestamp(t / 1000000, _LOCAL_TIMEZONE)
def _convert_timestamp(s):
- return _datetime.datetime.fromtimestamp(int(s) / 1000000)
+ return _datetime.datetime.fromtimestamp(int(s) / 1000000, _LOCAL_TIMEZONE)
def _convert_trivial(x):
diff --git a/systemd/test/test_journal.py b/systemd/test/test_journal.py
index 2f3cd3b..e6761ca 100644
--- a/systemd/test/test_journal.py
+++ b/systemd/test/test_journal.py
@@ -290,6 +290,18 @@ def test_reader_convert_entry(tmpdir):
'x2' : ['YYY', 'YYY'],
'y2' : [b'\200\200', b'\200\201']}
+def test_reader_convert_timestamps(tmpdir):
+ j = journal.Reader(path=tmpdir.strpath)
+
+ val = j._convert_field('_SOURCE_REALTIME_TIMESTAMP', 1641651559324187)
+ assert val.tzinfo is not None
+
+ val = j._convert_field('__REALTIME_TIMESTAMP', 1641651559324187)
+ assert val.tzinfo is not None
+
+ val = j._convert_field('COREDUMP_TIMESTAMP', 1641651559324187)
+ assert val.tzinfo is not None
+
def test_seek_realtime(tmpdir):
j = journal.Reader(path=tmpdir.strpath)