syslogformat


Namesyslogformat JSON
Version 1.0.0 PyPI version JSON
download
home_page
SummaryPython `logging.Formatter` class for syslog style messages
upload_time2023-11-15 19:19:34
maintainer
docs_urlNone
author
requires_python<4.0,>=3.8
licenseApache Software License Version 2.0
keywords logging formatting syslog
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # syslogformat

**Python [`logging.Formatter`][1] class for [syslog][2] style messages**

[![GitHub last commit][github-last-commit-img]][github-last-commit]
[![License: Apache-2.0][apache2-img]][apache2]
[![PyPI version][pypi-latest-version-img]][pypi-latest-version]

[📑 Documentation][3] &nbsp; | &nbsp; [🧑‍💻 Source Code][4] &nbsp; | &nbsp; [🐛 Bug Tracker][5]

## Installation

`pip install syslogformat`

## Usage

### Basic configuration

As is the case with any logging formatter setup, you need to use the special `()` key to indicate the custom class to use.
(See the [Dictionary Schema Details][6] and [User-defined objects][7] sections in the official `logging.config` documentation.)

For example, you could use the following config dictionary, pass it to the [`logging.config.dictConfig`][8] function, and start logging like this:

```python hl_lines="7"
import logging.config

log_config = {
    "version": 1,
    "formatters": {
        "my_syslog_formatter": {
            "()": "syslogformat.SyslogFormatter",
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "formatter": "my_syslog_formatter",
            "stream": "ext://sys.stdout",
        }
    },
    "root": {"handlers": ["console"], "level": "DEBUG"},
}
logging.config.dictConfig(log_config)

logging.debug("foo")
logging.info("bar")
logging.warning("baz")
try:
    raise ValueError("this is bad")
except ValueError as e:
    logging.exception("oof")
```

This will send the following to your stdout:

```
<15>foo | root
<14>bar | root
<12>baz | root
<11>oof | root --> Traceback (most recent call last): --> File "/path/to/module.py", line 26, in <module> --> raise ValueError("this is bad") --> ValueError: this is bad
```

### The `PRI` prefix

To adhere to the `syslog` standard outlined in RFC 3164, every log message must begin with the so called [`PRI` part][9].
This is a code enclosed in angle brackets that indicates the **facility** generating the message and **severity** of the event.
The facility is encoded as an integer between 0 and 23 and the severity is encoded as an integer between 0 and 7.
The `PRI` code is calculated by multiplying the facility by 8 and adding the severity.

Programs like **`systemd-journald`** hide the `PRI` part in their output, but interpret it behind the scenes to allow things like highlighting messages of a certain level a different color and filtering by severity.

By default the facility code `1` is used, which indicates user-level messages, but this can be easily configured (see below).
Since a `DEBUG` log message corresponds to a severity of `7`, the resulting `PRI` part of the first log message in the example above is `<15>` (since `1 * 8 + 7 == 15`).
An `ERROR` has the severity `3`, so that message has the `PRI` part `<11>`.

### Default message format

By default the message format of the `SyslogFormatter` is `%(message)s | %(name)s` (and equivalent for `$` or `{` [styles][10]).

In addition, all line-breaks (including those in the exception traceback) are replaced with ` --> ` by default.

All of this can be easily changed and configured to fit your needs (see below).

### Configuration options

In addition to the usual [formatter options][11], the `SyslogFormatter` provides the following parameters:

| Parameter         | Description                                                                                                                                                                            | Default |
|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------:|
| `facility`        | The facility value to use for every log message                                                                                                                                        |   `1`   |
| `line_break_repl` | To prevent a single log message taking up more than one line, every line-break (and consecutive whitespace) is replaced with this string. Passing `None` disables this behavior.       | ` --> ` |
| `level_formats`   | If provided a mapping of log level thresholds to format strings, the formatter will prioritize the format with the highest level threshold for all log records at or above that level. | `None`  |

For more details, check the API of the `SyslogFormatter` constructor in the [documentation][3].

### Extended configuration example

Here is an example using a [custom message format][12] and specifying a different facility and line break replacement:

```python hl_lines="8-11"
import logging.config

log_config = {
    "version": 1,
    "formatters": {
        "my_syslog_formatter": {
            "()": "syslogformat.SyslogFormatter",
            "format": "{levelname:<8}{message} [{name}]",
            "style": "{",
            "facility": 16,
            "line_break_repl": " 🚀 ",
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "formatter": "my_syslog_formatter",
            "stream": "ext://sys.stdout",
        }
    },
    "root": {"handlers": ["console"], "level": "DEBUG"},
}
logging.config.dictConfig(log_config)

logging.debug("foo")
logging.info("bar")
logging.warning("baz")
try:
    raise ValueError("this is bad")
except ValueError as e:
    logging.exception("oof")
```

Output:

```
<135>DEBUG   foo [root]
<134>INFO    bar [root]
<132>WARNING baz [root]
<131>ERROR   oof [root] 🚀 Traceback (most recent call last): 🚀 File "/path/to/module.py", line 30, in <module> 🚀 raise ValueError("this is bad") 🚀 ValueError: this is bad
```

Since the facility was set to `16`, the PRI code ends up being `16 * 8 + 7 == 135` for `DEBUG` level messages and `16 * 8 + 3 == 131` for `ERROR` messages.

Exception texts are of course still appended, when the `exception` log method is called (or the `exc_info` argument is passed), but the custom `line_break_repl` here is used for reformatting those texts.

## Dependencies

- Python `>=3.8` `<=3.12`
- No third-party dependencies
- OS agnostic


[github-last-commit]: https://github.com/daniil-berg/syslogformat/commits
[github-last-commit-img]: https://img.shields.io/github/last-commit/daniil-berg/syslogformat?label=Last%20commit&logo=git
[apache2]: https://apache.org/licenses/LICENSE-2.0
[apache2-img]: https://img.shields.io/badge/Apache-2.0-darkred.svg?logo=apache
[pypi-latest-version]: https://pypi.org/project/syslogformat/
[pypi-latest-version-img]: https://img.shields.io/pypi/v/syslogformat?color=teal&logo=pypi

[1]:  https://docs.python.org/3/library/logging.html#formatter-objects
[2]:  https://datatracker.ietf.org/doc/html/rfc3164#section-4.1
[3]:  https://daniil-berg.github.io/syslogformat
[4]:  https://github.com/daniil-berg/syslogformat
[5]:  https://github.com/daniil-berg/syslogformat/issues
[6]:  https://docs.python.org/3/library/logging.config.html#dictionary-schema-details
[7]:  https://docs.python.org/3/library/logging.config.html#logging-config-dict-userdef
[8]:  https://docs.python.org/3/library/logging.config.html#logging.config.dictConfig
[9]:  https://datatracker.ietf.org/doc/html/rfc3164#section-4.1.1
[10]: https://docs.python.org/3/howto/logging-cookbook.html#formatting-styles
[11]: https://docs.python.org/3/library/logging.html#logging.Formatter
[12]: https://docs.python.org/3/library/logging.html#logrecord-attributes

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "syslogformat",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "<4.0,>=3.8",
    "maintainer_email": "Daniil Fajnberg <mail@daniil.fajnberg.de>",
    "keywords": "logging,formatting,syslog",
    "author": "",
    "author_email": "Daniil Fajnberg <mail@daniil.fajnberg.de>",
    "download_url": "https://files.pythonhosted.org/packages/00/67/976ab275fd7b8b1f0d991780a04341a13f4997d48d0df5104f27549c180b/syslogformat-1.0.0.tar.gz",
    "platform": null,
    "description": "# syslogformat\n\n**Python [`logging.Formatter`][1] class for [syslog][2] style messages**\n\n[![GitHub last commit][github-last-commit-img]][github-last-commit]\n[![License: Apache-2.0][apache2-img]][apache2]\n[![PyPI version][pypi-latest-version-img]][pypi-latest-version]\n\n[\ud83d\udcd1 Documentation][3] &nbsp; | &nbsp; [\ud83e\uddd1\u200d\ud83d\udcbb Source Code][4] &nbsp; | &nbsp; [\ud83d\udc1b Bug Tracker][5]\n\n## Installation\n\n`pip install syslogformat`\n\n## Usage\n\n### Basic configuration\n\nAs is the case with any logging formatter setup, you need to use the special `()` key to indicate the custom class to use.\n(See the [Dictionary Schema Details][6] and [User-defined objects][7] sections in the official `logging.config` documentation.)\n\nFor example, you could use the following config dictionary, pass it to the [`logging.config.dictConfig`][8] function, and start logging like this:\n\n```python hl_lines=\"7\"\nimport logging.config\n\nlog_config = {\n    \"version\": 1,\n    \"formatters\": {\n        \"my_syslog_formatter\": {\n            \"()\": \"syslogformat.SyslogFormatter\",\n        }\n    },\n    \"handlers\": {\n        \"console\": {\n            \"class\": \"logging.StreamHandler\",\n            \"level\": \"DEBUG\",\n            \"formatter\": \"my_syslog_formatter\",\n            \"stream\": \"ext://sys.stdout\",\n        }\n    },\n    \"root\": {\"handlers\": [\"console\"], \"level\": \"DEBUG\"},\n}\nlogging.config.dictConfig(log_config)\n\nlogging.debug(\"foo\")\nlogging.info(\"bar\")\nlogging.warning(\"baz\")\ntry:\n    raise ValueError(\"this is bad\")\nexcept ValueError as e:\n    logging.exception(\"oof\")\n```\n\nThis will send the following to your stdout:\n\n```\n<15>foo | root\n<14>bar | root\n<12>baz | root\n<11>oof | root --> Traceback (most recent call last): --> File \"/path/to/module.py\", line 26, in <module> --> raise ValueError(\"this is bad\") --> ValueError: this is bad\n```\n\n### The `PRI` prefix\n\nTo adhere to the `syslog` standard outlined in RFC 3164, every log message must begin with the so called [`PRI` part][9].\nThis is a code enclosed in angle brackets that indicates the **facility** generating the message and **severity** of the event.\nThe facility is encoded as an integer between 0 and 23 and the severity is encoded as an integer between 0 and 7.\nThe `PRI` code is calculated by multiplying the facility by 8 and adding the severity.\n\nPrograms like **`systemd-journald`** hide the `PRI` part in their output, but interpret it behind the scenes to allow things like highlighting messages of a certain level a different color and filtering by severity.\n\nBy default the facility code `1` is used, which indicates user-level messages, but this can be easily configured (see below).\nSince a `DEBUG` log message corresponds to a severity of `7`, the resulting `PRI` part of the first log message in the example above is `<15>` (since `1 * 8 + 7 == 15`).\nAn `ERROR` has the severity `3`, so that message has the `PRI` part `<11>`.\n\n### Default message format\n\nBy default the message format of the `SyslogFormatter` is `%(message)s | %(name)s` (and equivalent for `$` or `{` [styles][10]).\n\nIn addition, all line-breaks (including those in the exception traceback) are replaced with ` --> ` by default.\n\nAll of this can be easily changed and configured to fit your needs (see below).\n\n### Configuration options\n\nIn addition to the usual [formatter options][11], the `SyslogFormatter` provides the following parameters:\n\n| Parameter         | Description                                                                                                                                                                            | Default |\n|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------:|\n| `facility`        | The facility value to use for every log message                                                                                                                                        |   `1`   |\n| `line_break_repl` | To prevent a single log message taking up more than one line, every line-break (and consecutive whitespace) is replaced with this string. Passing `None` disables this behavior.       | ` --> ` |\n| `level_formats`   | If provided a mapping of log level thresholds to format strings, the formatter will prioritize the format with the highest level threshold for all log records at or above that level. | `None`  |\n\nFor more details, check the API of the `SyslogFormatter` constructor in the [documentation][3].\n\n### Extended configuration example\n\nHere is an example using a [custom message format][12] and specifying a different facility and line break replacement:\n\n```python hl_lines=\"8-11\"\nimport logging.config\n\nlog_config = {\n    \"version\": 1,\n    \"formatters\": {\n        \"my_syslog_formatter\": {\n            \"()\": \"syslogformat.SyslogFormatter\",\n            \"format\": \"{levelname:<8}{message} [{name}]\",\n            \"style\": \"{\",\n            \"facility\": 16,\n            \"line_break_repl\": \" \ud83d\ude80 \",\n        }\n    },\n    \"handlers\": {\n        \"console\": {\n            \"class\": \"logging.StreamHandler\",\n            \"level\": \"DEBUG\",\n            \"formatter\": \"my_syslog_formatter\",\n            \"stream\": \"ext://sys.stdout\",\n        }\n    },\n    \"root\": {\"handlers\": [\"console\"], \"level\": \"DEBUG\"},\n}\nlogging.config.dictConfig(log_config)\n\nlogging.debug(\"foo\")\nlogging.info(\"bar\")\nlogging.warning(\"baz\")\ntry:\n    raise ValueError(\"this is bad\")\nexcept ValueError as e:\n    logging.exception(\"oof\")\n```\n\nOutput:\n\n```\n<135>DEBUG   foo [root]\n<134>INFO    bar [root]\n<132>WARNING baz [root]\n<131>ERROR   oof [root] \ud83d\ude80 Traceback (most recent call last): \ud83d\ude80 File \"/path/to/module.py\", line 30, in <module> \ud83d\ude80 raise ValueError(\"this is bad\") \ud83d\ude80 ValueError: this is bad\n```\n\nSince the facility was set to `16`, the PRI code ends up being `16 * 8 + 7 == 135` for `DEBUG` level messages and `16 * 8 + 3 == 131` for `ERROR` messages.\n\nException texts are of course still appended, when the `exception` log method is called (or the `exc_info` argument is passed), but the custom `line_break_repl` here is used for reformatting those texts.\n\n## Dependencies\n\n- Python `>=3.8` `<=3.12`\n- No third-party dependencies\n- OS agnostic\n\n\n[github-last-commit]: https://github.com/daniil-berg/syslogformat/commits\n[github-last-commit-img]: https://img.shields.io/github/last-commit/daniil-berg/syslogformat?label=Last%20commit&logo=git\n[apache2]: https://apache.org/licenses/LICENSE-2.0\n[apache2-img]: https://img.shields.io/badge/Apache-2.0-darkred.svg?logo=apache\n[pypi-latest-version]: https://pypi.org/project/syslogformat/\n[pypi-latest-version-img]: https://img.shields.io/pypi/v/syslogformat?color=teal&logo=pypi\n\n[1]:  https://docs.python.org/3/library/logging.html#formatter-objects\n[2]:  https://datatracker.ietf.org/doc/html/rfc3164#section-4.1\n[3]:  https://daniil-berg.github.io/syslogformat\n[4]:  https://github.com/daniil-berg/syslogformat\n[5]:  https://github.com/daniil-berg/syslogformat/issues\n[6]:  https://docs.python.org/3/library/logging.config.html#dictionary-schema-details\n[7]:  https://docs.python.org/3/library/logging.config.html#logging-config-dict-userdef\n[8]:  https://docs.python.org/3/library/logging.config.html#logging.config.dictConfig\n[9]:  https://datatracker.ietf.org/doc/html/rfc3164#section-4.1.1\n[10]: https://docs.python.org/3/howto/logging-cookbook.html#formatting-styles\n[11]: https://docs.python.org/3/library/logging.html#logging.Formatter\n[12]: https://docs.python.org/3/library/logging.html#logrecord-attributes\n",
    "bugtrack_url": null,
    "license": "Apache Software License Version 2.0",
    "summary": "Python `logging.Formatter` class for syslog style messages",
    "version": "1.0.0",
    "project_urls": {
        "Documentation": "http://daniil-berg.github.io/syslogformat",
        "Issue Tracker": "https://github.com/daniil-berg/syslogformat/issues",
        "Repository": "https://github.com/daniil-berg/syslogformat"
    },
    "split_keywords": [
        "logging",
        "formatting",
        "syslog"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d998f5bed1f2efb472411fcc2668ef20bd588183478d01724e7d4a1672f03b92",
                "md5": "7eef7352b087ac0f92eeda5b355aeb8f",
                "sha256": "ff7375f341098e802ef7225e56290f789578ddc6a235365475af42456e7ea3c2"
            },
            "downloads": -1,
            "filename": "syslogformat-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7eef7352b087ac0f92eeda5b355aeb8f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.8",
            "size": 17593,
            "upload_time": "2023-11-15T19:19:33",
            "upload_time_iso_8601": "2023-11-15T19:19:33.184605Z",
            "url": "https://files.pythonhosted.org/packages/d9/98/f5bed1f2efb472411fcc2668ef20bd588183478d01724e7d4a1672f03b92/syslogformat-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0067976ab275fd7b8b1f0d991780a04341a13f4997d48d0df5104f27549c180b",
                "md5": "89a226edad0ac4208bc6c6dca11a2f99",
                "sha256": "83bd396047892f72bad0387f7310fc5f6ab84df556e59c0b76d34d6f0e5e1838"
            },
            "downloads": -1,
            "filename": "syslogformat-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "89a226edad0ac4208bc6c6dca11a2f99",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.8",
            "size": 26265,
            "upload_time": "2023-11-15T19:19:34",
            "upload_time_iso_8601": "2023-11-15T19:19:34.831833Z",
            "url": "https://files.pythonhosted.org/packages/00/67/976ab275fd7b8b1f0d991780a04341a13f4997d48d0df5104f27549c180b/syslogformat-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-15 19:19:34",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "daniil-berg",
    "github_project": "syslogformat",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "syslogformat"
}
        
Elapsed time: 0.20790s