Skip to main content

systemd wrapper in Cython

Project description

pypi version License

systemd wrapper in Cython

Python systemd wrapper using Cython.

Installation

About Binary Wheels Distribution

Historically, cysystemd was not distributed via wheels due to systemd versioning challenges. While the libsystemd headers remain relatively stable, the ABI can vary between different OS versions and distributions. Previous attempts to distribute wheels resulted in compatibility issues across different Linux systems. Currently, we use the manylinux_2_34 format for wheel distribution, which bundles the necessary shared objects (.so files) required for operation.

This approach should provide compatibility with modern systemd installations.

However, if you encounter any compatibility issues, we strongly recommend installing the package from source code instead.

pip install --no-binary=:all: cysystemd

Installation from PyPI

Once the system dependencies are installed, you can install cysystemd:

pip install cysystemd

Installation from Source

You must install the systemd development headers (libsystemd) before installation! Without these headers, the installation will fail.

For Debian/Ubuntu users:

apt install build-essential libsystemd-dev

On older versions of Debian/Ubuntu, you might also need:

apt install libsystemd-daemon-dev libsystemd-journal-dev

For CentOS/RHEL:

yum install gcc systemd-devel

BREAKING CHANGES in v2.0.0

AsyncJournalReader Changes

  1. Major refactoring of the AsyncJournalReader iterator implementation:

    • Removed internal queue and threading-based implementation
    • Now uses direct async iteration through journal events
    • More reliable handling of journal invalidation events
    • Simpler and more efficient implementation
  2. wait() method now returns JournalEvent instead of boolean

    • Returns specific event type (JournalEvent.APPEND, JournalEvent.INVALIDATE, JournalEvent.NOP)
    • Better error handling and event processing

Type Annotations

  • Added comprehensive type hints throughout the codebase
  • Added return type annotations for all public methods
  • Enhanced IDE support and code documentation

API Behavior Changes

  • seek_tail() now automatically calls previous() to ensure cursor is positioned correctly
  • Improved error handling and validation in various methods
  • More consistent return types across the API

Python Support

  • Added support for Python 3.13
  • Maintained support for Python 3.8-3.12

Dependency Changes

  • Requires latest libsystemd development headers
  • Binary wheels are no longer distributed (see "Why binary wheels are no longer distributed" above)

Please ensure your code is updated to handle these changes when upgrading to version 2.0.0.

Usage examples

Writing to journald

Logging handler for python logger

from cysystemd import journal
import logging
import uuid

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger()
logger.addHandler(journal.JournaldLogHandler())

try:
    logger.info("Trying to do something")
    raise Exception('foo')
except:
    logger.exception("Test Exception %s", 1)

systemd daemon notification

from cysystemd.daemon import notify, Notification

# Send READY=1
notify(Notification.READY)

# Send status
notify(Notification.STATUS, "I'm fine.")

# Send stopping
notify(Notification.STOPPING)

Write message into systemd journal:

from cysystemd import journal


journal.write("Hello Lennart")

# Or send structured data
journal.send(
    message="Hello Lennart",
    priority=journal.Priority.INFO,
    some_field='some value',
)

Reading journald

Reading all systemd records

from cysystemd.reader import JournalReader, JournalOpenMode

journal_reader = JournalReader()
journal_reader.open(JournalOpenMode.SYSTEM)
journal_reader.seek_head()

for record in journal_reader:
    print(record.data['MESSAGE'])

Read only cron logs

from cysystemd.reader import JournalReader, JournalOpenMode, Rule


rules = (
  Rule("SYSLOG_IDENTIFIER", "CRON") &
  Rule("_SYSTEMD_UNIT", "crond.service") |
  Rule("_SYSTEMD_UNIT", "cron.service")
)

cron_reader = JournalReader()
cron_reader.open(JournalOpenMode.SYSTEM)
cron_reader.seek_head()
cron_reader.add_filter(rules)

for record in cron_reader:
    print(record.data['MESSAGE'])

Polling records

from cysystemd.reader import JournalReader, JournalOpenMode


reader = JournalReader()
reader.open(JournalOpenMode.SYSTEM)
reader.seek_tail()

poll_timeout = 255

while True:
    reader.wait(poll_timeout)

    for record in reader:
       print(record.data['MESSAGE'])

journald open modes

  • CURRENT_USER
  • LOCAL_ONLY
  • RUNTIME_ONLY
  • SYSTEM
  • SYSTEM_ONLY - deprecated alias of SYSTEM
from cysystemd.reader import JournalReader, JournalOpenMode


reader = JournalReader()
reader.open(JournalOpenMode.CURRENT_USER)

journald entry

JournalEntry class has some special properties and methods:

  • data - journal entry content (dict)
  • date - entry timestamp (datetime instance)
  • cursor - systemd identification bytes for this entry
  • boot_id() - returns bootid
  • get_realtime_sec() - entry epoch (float)
  • get_realtime_usec() - entry epoch (int microseconds)
  • get_monotonic_sec() - entry monotonic time (float)
  • get_monotonic_usec() - entry monotonic time (int microseconds)
  • __getitem__(key) - shoutcut for entry.data[key]

journald reader

JournalReader class has some special properties and methods:

  • open(flags=JournalOpenMode.CURRENT_USER) - opening journald with selected mode
  • open_directory(path) - opening journald from path
  • open_files(*filename) - opening journald from files
  • data_threshold - may be used to get or set the data field size threshold for data returned by fething entry data.
  • closed - returns True when journal reader closed
  • locked - returns True when journal reader locked
  • idle - returns True when journal reader opened
  • seek_head - move reader pointer to the first entry
  • seek_tail - move reader pointer to the last entry
  • seek_monotonic_usec - seeks to the entry with the specified monotonic timestamp, i.e. CLOCK_MONOTONIC. Since monotonic time restarts on every reboot a boot ID needs to be specified as well.
  • seek_realtime_usec - seeks to the entry with the specified realtime (wallclock) timestamp, i.e. CLOCK_REALTIME. Note that the realtime clock is not necessarily monotonic. If a realtime timestamp is ambiguous, it is not defined which position is sought to.
  • seek_cursor - seeks to the entry located at the specified cursor (see JournalEntry.cursor).
  • wait(timeout) - It will synchronously wait until the journal gets changed. The maximum time this call sleeps may be controlled with the timeout_usec parameter.
  • __iter__ - returns JournalReader object
  • __next__ - calls next() or raise StopIteration
  • next(skip=0) - returns the next JournalEntry. The skip parameter skips some entries.
  • previous(skip=0) - returns the previous JournalEntry. The skip parameter skips some entries.
  • skip_next(skip) - skips next entries.
  • skip_previous(skip) - skips next entries.
  • add_filter(rule) - adding filter rule. See read-only-cron-logs_ as example.
  • clear_filter - reset all filters
  • fd - returns a special file descriptor
  • events - returns EPOLL events
  • timeout - returns internal timeout
  • process_events() - After each poll() wake-up process_events() needs to be called to process events. This call will also indicate what kind of change has been detected.
  • get_catalog() - retrieves a message catalog entry for the current journal entry. This will look up an entry in the message catalog by using the "MESSAGE_ID=" field of the current journal entry. Before returning the entry all journal field names in the catalog entry text enclosed in "@" will be replaced by the respective field values of the current entry. If a field name referenced in the message catalog entry does not exist, in the current journal entry, the "@" will be removed, but the field name otherwise left untouched.
  • get_catalog_for_message_id(message_id: UUID) - works similar to get_catalog() but the entry is looked up by the specified message ID (no open journal context is necessary for this), and no field substitution is performed.

Asyncio support

Initial asyncio support for reading journal asynchronously.

AsyncJournalReader

Blocking methods were wrapped by threads. Method wait() use epoll on journald file descriptor.

import asyncio
import json

from cysystemd.reader import JournalOpenMode
from cysystemd.async_reader import AsyncJournalReader


async def main():
    reader = AsyncJournalReader()
    await reader.open(JournalOpenMode.SYSTEM)
    await reader.seek_tail()

    async for record in reader:
        print(json.dumps(record.data, indent=1, sort_keys=True))

if __name__ == '__main__':
    asyncio.run(main())

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cysystemd-2.0.1.tar.gz (304.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

cysystemd-2.0.1-cp313-cp313-manylinux_2_34_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ x86-64

cysystemd-2.0.1-cp313-cp313-manylinux_2_34_aarch64.whl (2.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ ARM64

cysystemd-2.0.1-cp312-cp312-manylinux_2_34_x86_64.whl (2.5 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

cysystemd-2.0.1-cp312-cp312-manylinux_2_34_aarch64.whl (2.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ ARM64

cysystemd-2.0.1-cp311-cp311-manylinux_2_34_x86_64.whl (2.5 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ x86-64

cysystemd-2.0.1-cp311-cp311-manylinux_2_34_aarch64.whl (2.3 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ ARM64

cysystemd-2.0.1-cp310-cp310-manylinux_2_34_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ x86-64

cysystemd-2.0.1-cp310-cp310-manylinux_2_34_aarch64.whl (2.3 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ ARM64

cysystemd-2.0.1-cp39-cp39-manylinux_2_34_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.34+ x86-64

cysystemd-2.0.1-cp39-cp39-manylinux_2_34_aarch64.whl (2.3 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.34+ ARM64

cysystemd-2.0.1-cp38-cp38-manylinux_2_34_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.34+ x86-64

cysystemd-2.0.1-cp38-cp38-manylinux_2_34_aarch64.whl (2.3 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.34+ ARM64

File details

Details for the file cysystemd-2.0.1.tar.gz.

File metadata

  • Download URL: cysystemd-2.0.1.tar.gz
  • Upload date:
  • Size: 304.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.0 CPython/3.10.11

File hashes

Hashes for cysystemd-2.0.1.tar.gz
Algorithm Hash digest
SHA256 632fe56264a18b7af3d1efd09125d6d5c1ec97d29ad6192c412ee43105821d61
MD5 3d6f02207d1db728246b74f57e375dc6
BLAKE2b-256 d22300950116890136fddd94fc6a176eb04f006e689bec4db5bf5727587ede09

See more details on using hashes here.

File details

Details for the file cysystemd-2.0.1-cp313-cp313-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for cysystemd-2.0.1-cp313-cp313-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 d9d89125cafee3cc0a898faf9fe53f9166ea6625393b75d606eef2901a8c3023
MD5 11cf19b10b11d34cb99d4bad3e254907
BLAKE2b-256 c88ac02db9ef01f0dc1dec06f0cbbe2e4132b119b6ae455a650d736b47fdd7a6

See more details on using hashes here.

File details

Details for the file cysystemd-2.0.1-cp313-cp313-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for cysystemd-2.0.1-cp313-cp313-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 017b924d42ee92f6736714b78d51f81aded6b5f34e44dc7e2e92cbe2598e3611
MD5 1151140e1fd055c8dbc3d69629ada16f
BLAKE2b-256 516648174df96d46d426d6a3bf605df21b10aa98752bd98f32b7e8e1edaddb08

See more details on using hashes here.

File details

Details for the file cysystemd-2.0.1-cp312-cp312-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for cysystemd-2.0.1-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 39b03dcfced76957ede5f3f21956b5687a0511bdd1d0d41f2d3dffc9df32320d
MD5 2ff48513328d71448dcf734d1ff2f875
BLAKE2b-256 2122afd2153b4100c7a8849a0810932c0636143b226d9ee0d8a761e233f0f8ce

See more details on using hashes here.

File details

Details for the file cysystemd-2.0.1-cp312-cp312-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for cysystemd-2.0.1-cp312-cp312-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 cd5543e1b1d96c5f327203506a46df96235e8b984cf0cfb4b85f0348975b7957
MD5 6827afa911d98a1882f832e03e84f3a3
BLAKE2b-256 6241ced57b3e8f65840c7a793baf0c53715ded901458cb3ff5c56225d7c39b23

See more details on using hashes here.

File details

Details for the file cysystemd-2.0.1-cp311-cp311-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for cysystemd-2.0.1-cp311-cp311-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 78dc5187193b2b959987e38c29d66e9fb625de5f93f2aec58eb7553aa504ed1d
MD5 0a9792056ec525a2c0b4e8c3cad34745
BLAKE2b-256 ac05699da6b7463c772312f6ef91784d199b65574a925019e18d7e56ba591858

See more details on using hashes here.

File details

Details for the file cysystemd-2.0.1-cp311-cp311-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for cysystemd-2.0.1-cp311-cp311-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 8f50d7d4057406c4b30ae5604f061687fcaa7c5e541935c7b4817166c870fc11
MD5 8a29845d7b128f5506adac64dfabc244
BLAKE2b-256 a5b986c887ec4879edcba99e6db1bcddc9c35e989a489a4761a3987be82f3957

See more details on using hashes here.

File details

Details for the file cysystemd-2.0.1-cp310-cp310-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for cysystemd-2.0.1-cp310-cp310-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 d0aaaa11ca96e706b1a2fbe2e9ec1c3739583e00ed88dcd1d987663b7b519870
MD5 5b7bef2e742019fc7232c73b270d10c0
BLAKE2b-256 588a52e8a2e41d37ae6f64309c5ab30e51848c27721f188ffab553a7fc32907a

See more details on using hashes here.

File details

Details for the file cysystemd-2.0.1-cp310-cp310-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for cysystemd-2.0.1-cp310-cp310-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 19a0b380622a11b42e7823e95a1f12312142d5a13d1b6e3cb400272e5aa3d07f
MD5 4a2b650f3f05ce16bebb1c732f661957
BLAKE2b-256 23e7aa5441ac05471ab606bb39f507650db01d4b6d6de49d84f7129a06d8928e

See more details on using hashes here.

File details

Details for the file cysystemd-2.0.1-cp39-cp39-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for cysystemd-2.0.1-cp39-cp39-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 0bb9b4380cb82202aeb5aedb5a6e63f257eac5d6192c24d054656e8329ab6cf0
MD5 5d520607a0a05ee4d0c9d8a8ca5ae0a7
BLAKE2b-256 15603f7e6417cf4618bad6ab77295e57c06d612361f6b63aa6f8ab83b694579f

See more details on using hashes here.

File details

Details for the file cysystemd-2.0.1-cp39-cp39-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for cysystemd-2.0.1-cp39-cp39-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 ed55acd18bcc576a5b1af81ae59fb86042ee019b642f6cfed9221b963f05aeea
MD5 f004596059456069c80a004694aee7e8
BLAKE2b-256 87f49e4c694d562ef7ddcf8bd93ac72ef750878374bfdde0f82dd8911f9147c0

See more details on using hashes here.

File details

Details for the file cysystemd-2.0.1-cp38-cp38-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for cysystemd-2.0.1-cp38-cp38-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 292f3f38b6fc6dc01a44c1053d8e2907ef857c09282fa904ed4742113eb36fdc
MD5 b73bc46213901d8360049e336fe8c1cd
BLAKE2b-256 6286606bb5fc2ed44b939029953e4f2b6bdccf029a10a3e2d4e402be455974a2

See more details on using hashes here.

File details

Details for the file cysystemd-2.0.1-cp38-cp38-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for cysystemd-2.0.1-cp38-cp38-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 b2dcd4f5788955787d08e43de1276cb5a6720e13e7fc6765aed4fe6fa3355144
MD5 64051e0aae7a043713528b8d76f0fad8
BLAKE2b-256 1617734a21206778bdd0a30ef173f6d6ed5ad31040f87ee9b04f4b929fa2b787

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page