%global _empty_manifest_terminate_build 0 Name: python-gelf-formatter Version: 0.2.1 Release: 1 Summary: GELF formatter for the Python standard library logging module. License: MIT URL: https://github.com/joaodrp/gelf-formatter Source0: https://mirrors.aliyun.com/pypi/web/packages/69/7c/4c4ed3d41e2fba4aa525583fa6bb86698e25c6567916d9553f942b5cd241/gelf-formatter-0.2.1.tar.gz BuildArch: noarch %description ## Motivation There are several packages available providing *handlers* for the standard library logging module that can send application logs to [Graylog](https://www.graylog.org/) by TCP/UDP/HTTP ([py-gelf](https://pypi.org/project/pygelf/) is a good example). Although these can be useful, it's not ideal to make an application performance dependent on network requests just for the purpose of delivering logs. Alternatively, one can simply log to a file or `stdout` and have a collector (like [Fluentd](https://www.fluentd.org/)) processing and sending those logs *asynchronously* to a remote server (and not just to Graylog, as GELF can be used as a generic log format), which is a common pattern for containerized applications. In a scenario like this all we need is a GELF logging *formatter*. ## Features - Support for arbitrary additional fields; - Support for including reserved [`logging.LogRecord`](https://docs.python.org/3/library/logging.html#logrecord-attributes) attributes as additional fields; - Exceptions detection with traceback formatting; - Zero dependencies and tiny footprint. ## Installation ### With pip ```text $ pip install gelf-formatter ``` ### From source ```text $ python setup.py install ``` ## Usage Simply create a `gelfformatter.GelfFormatter` instance and pass it as argument to [`logging.Handler.setFormatter`](https://docs.python.org/3/library/logging.html#logging.Handler.setFormatter): ```python import sys import logging from gelfformatter import GelfFormatter formatter = GelfFormatter() handler = logging.StreamHandler(sys.stdout) handler.setFormatter(formatter) ``` Apply it globally with [`logging.basicConfig`](https://docs.python.org/3/library/logging.html#logging.basicConfig) to automatically format log records from third-party packages as well: ```python logging.basicConfig(level=logging.DEBUG, handlers=[handler]) ``` Alternatively, you can configure a local [`logging.Logger`](https://docs.python.org/3/library/logging.html#logging.Logger) instance through [`logging.Logger.addHandler`](https://docs.python.org/3/library/logging.html#logging.Logger.addHandler): ```python logger = logging.getLogger('my-app') logger.addHandler(handler) ``` That's it. You can now use the logging module as usual, all records will be formatted as GELF messages. ### Standard Fields The formatter will output all (non-deprecated) fields described in the [GELF Payload Specification (version 1.1)](http://docs.graylog.org/en/latest/pages/gelf.html#gelf-payload-specification): - `version`: String, always set to `1.1`; - `host`: String, the output of [`socket.gethostname`](https://docs.python.org/3/library/socket.html#socket.gethostname) at initialization; - `short_message`: String, log record message; - `full_message` (*optional*): String, formatted exception traceback (if any); - `timestamp`: Number, time in seconds since the epoch as a floating point; - `level`: Integer, *syslog* severity level. None of these fields can be ignored, renamed or overridden. #### Example ```python logging.info("Some message") ``` ```text {"version":"1.1","host":"my-server","short_message":"Some message","timestamp":1557342545.1067393,"level":6} ``` #### Exceptions The `full_message` field is used to store the traceback of exceptions. You just need to log them with [`logging.exception`](https://docs.python.org/3/library/logging.html#logging.exception). ##### Example ```python import urllib.request req = urllib.request.Request('http://www.pythonnn.org') try: urllib.request.urlopen(req) except urllib.error.URLError as e: logging.exception(e.reason) ``` ```text {"version": "1.1", "short_message": "[Errno -2] Name or service not known", "timestamp": 1557342714.0695107, "level": 3, "host": "my-server", "full_message": "Traceback (most recent call last):\n ...(truncated)... raise URLError(err)\nurllib.error.URLError: "} ``` ### Additional Fields The GELF specification allows arbitrary additional fields, with keys prefixed with an underscore. To include additional fields use the standard logging `extra` keyword. Keys will be automatically prefixed with an underscore (if not already). #### Example ```python logging.info("request received", extra={"path": "/orders/1", "method": "GET"}) ``` ```text {"version": "1.1", "short_message": "request received", "timestamp": 1557343604.5892842, "level": 6, "host": "my-server", "_path": "/orders/1", "_method": "GET"} ``` #### Reserved Fields By default the formatter ignores all [`logging.LogRecord` attributes](https://docs.python.org/3/library/logging.html#logrecord-attributes). You can however opt to include them as additional fields. This can be used to display useful information like the current module, filename, line number, etc. To do so, simply pass a list of `LogRecord` attribute names as value of the `allowed_reserved_attrs` keyword when initializing a `GelfFormatter`. You can also modify the `allowed_reserved_attrs` instance variable of an already initialized formatter. ##### Example ```python attrs = ["lineno", "module", "filename"] formatter = GelfFormatter(allowed_reserved_attrs=attrs) # or formatter.allowed_reserved_attrs = attrs logging.debug("starting application...") ``` ```text {"version": "1.1", "short_message": "starting application...", "timestamp": 1557346554.989846, "level": 6, "host": "my-server", "_lineno": 175, "_module": "myapp", "_filename": "app.py"} ``` You can optionally customize the name of these additional fields using a [`logging.Filter`](https://docs.python.org/3/library/logging.html#filter-objects) (see below). Similarily, you can choose to ignore additional attributes passed via the `extra` keyword argument. This can be usefull to e.g. not log keywords named `secret` or `password`. To do so, pass a list of names to the `ignored_attrs` keyword when initializing a `GelfFormatter`. You can also modify the `ignored_attrs` instance variable of an already initialized formatter. ##### Example But be aware: nested fields will be printed! Only the root level of keywords is filtered by the `ignored_attrs`. ```python attrs = ["secret", "password"] formatter = GelfFormatter(ignored_attrs=attrs) # or formatter.ignored_attrs = attrs logging.debug("app config", extra={"connection": "local", "secret": "verySecret!", "mysql": {"user": "test", "password": "will_be_logged"}}) ``` ```text {"version": "1.1", "short_message": "app config", "timestamp": 1557346554.989846, "level": 6, "host": "my-server", "_connection": "local", "_mysql": {"user": "test", "password": "will_be_logged"}} ``` #### Context Fields Having the ability to define a set of additional fields once and have them included in all log messages can be useful to avoid repetitive `extra` key/value pairs and enable contextual logging. Python's logging module provides several options to add context to a logger, among which we highlight the [`logging.LoggerAdapter`](https://docs.python.org/3/library/logging.html#loggeradapter-objects) and [`logging.Filter`](https://docs.python.org/3/library/logging.html#filter-objects). Between these we recommend a `logging.Filter`, which is simpler and can be attached directly to a [`logging.Handler`](https://docs.python.org/3/library/logging.html#handler-objects). A `logging.Filter` can therefore be used locally (on a [`logging.Logger`](https://docs.python.org/3/library/logging.html#logger-objects)) or globally (through `logging.basicConfig`). If you opt for a `LoggerAdapter` you'll need a `logging.Logger` to wrap. You can also use a `logging.Filter` to reuse/rename any of the reserved `logging.LogRecord` attributes. ##### Example ```python class ContextFilter(logging.Filter): def filter(self, record): # Add any number of arbitrary additional fields record.app = "my-app" record.app_version = "1.2.3" record.environment = os.environ.get("APP_ENV") # Reuse any reserved `logging.LogRecord` attributes record.file = record.filename record.line = record.lineno return True formatter = GelfFormatter() handler = logging.StreamHandler(sys.stdout) handler.setFormatter(formatter) handler.addFilter(ContextFilter()) logging.basicConfig(level=logging.DEBUG, handlers=[handler]) logging.info("hi", extra=dict(foo="bar")) ``` ```text {"version": "1.1", "short_message": "hi", "timestamp": 1557431642.189755, "level": 6, "host": "my-server", "_foo": "bar", "_app": "my-app", "_app_version": "1.2.3", "_environment": "development", "_file": "app.py", "_line": 159} ``` ## Pretty-Print Looking for a GELF log pretty-printer? If so, have a look at [gelf-pretty](https://github.com/joaodrp/gelf-pretty) :fire: ## Contributions This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please refer to our [contributing guide](CONTRIBUTING.md) for further information. %package -n python3-gelf-formatter Summary: GELF formatter for the Python standard library logging module. Provides: python-gelf-formatter BuildRequires: python3-devel BuildRequires: python3-setuptools BuildRequires: python3-pip %description -n python3-gelf-formatter ## Motivation There are several packages available providing *handlers* for the standard library logging module that can send application logs to [Graylog](https://www.graylog.org/) by TCP/UDP/HTTP ([py-gelf](https://pypi.org/project/pygelf/) is a good example). Although these can be useful, it's not ideal to make an application performance dependent on network requests just for the purpose of delivering logs. Alternatively, one can simply log to a file or `stdout` and have a collector (like [Fluentd](https://www.fluentd.org/)) processing and sending those logs *asynchronously* to a remote server (and not just to Graylog, as GELF can be used as a generic log format), which is a common pattern for containerized applications. In a scenario like this all we need is a GELF logging *formatter*. ## Features - Support for arbitrary additional fields; - Support for including reserved [`logging.LogRecord`](https://docs.python.org/3/library/logging.html#logrecord-attributes) attributes as additional fields; - Exceptions detection with traceback formatting; - Zero dependencies and tiny footprint. ## Installation ### With pip ```text $ pip install gelf-formatter ``` ### From source ```text $ python setup.py install ``` ## Usage Simply create a `gelfformatter.GelfFormatter` instance and pass it as argument to [`logging.Handler.setFormatter`](https://docs.python.org/3/library/logging.html#logging.Handler.setFormatter): ```python import sys import logging from gelfformatter import GelfFormatter formatter = GelfFormatter() handler = logging.StreamHandler(sys.stdout) handler.setFormatter(formatter) ``` Apply it globally with [`logging.basicConfig`](https://docs.python.org/3/library/logging.html#logging.basicConfig) to automatically format log records from third-party packages as well: ```python logging.basicConfig(level=logging.DEBUG, handlers=[handler]) ``` Alternatively, you can configure a local [`logging.Logger`](https://docs.python.org/3/library/logging.html#logging.Logger) instance through [`logging.Logger.addHandler`](https://docs.python.org/3/library/logging.html#logging.Logger.addHandler): ```python logger = logging.getLogger('my-app') logger.addHandler(handler) ``` That's it. You can now use the logging module as usual, all records will be formatted as GELF messages. ### Standard Fields The formatter will output all (non-deprecated) fields described in the [GELF Payload Specification (version 1.1)](http://docs.graylog.org/en/latest/pages/gelf.html#gelf-payload-specification): - `version`: String, always set to `1.1`; - `host`: String, the output of [`socket.gethostname`](https://docs.python.org/3/library/socket.html#socket.gethostname) at initialization; - `short_message`: String, log record message; - `full_message` (*optional*): String, formatted exception traceback (if any); - `timestamp`: Number, time in seconds since the epoch as a floating point; - `level`: Integer, *syslog* severity level. None of these fields can be ignored, renamed or overridden. #### Example ```python logging.info("Some message") ``` ```text {"version":"1.1","host":"my-server","short_message":"Some message","timestamp":1557342545.1067393,"level":6} ``` #### Exceptions The `full_message` field is used to store the traceback of exceptions. You just need to log them with [`logging.exception`](https://docs.python.org/3/library/logging.html#logging.exception). ##### Example ```python import urllib.request req = urllib.request.Request('http://www.pythonnn.org') try: urllib.request.urlopen(req) except urllib.error.URLError as e: logging.exception(e.reason) ``` ```text {"version": "1.1", "short_message": "[Errno -2] Name or service not known", "timestamp": 1557342714.0695107, "level": 3, "host": "my-server", "full_message": "Traceback (most recent call last):\n ...(truncated)... raise URLError(err)\nurllib.error.URLError: "} ``` ### Additional Fields The GELF specification allows arbitrary additional fields, with keys prefixed with an underscore. To include additional fields use the standard logging `extra` keyword. Keys will be automatically prefixed with an underscore (if not already). #### Example ```python logging.info("request received", extra={"path": "/orders/1", "method": "GET"}) ``` ```text {"version": "1.1", "short_message": "request received", "timestamp": 1557343604.5892842, "level": 6, "host": "my-server", "_path": "/orders/1", "_method": "GET"} ``` #### Reserved Fields By default the formatter ignores all [`logging.LogRecord` attributes](https://docs.python.org/3/library/logging.html#logrecord-attributes). You can however opt to include them as additional fields. This can be used to display useful information like the current module, filename, line number, etc. To do so, simply pass a list of `LogRecord` attribute names as value of the `allowed_reserved_attrs` keyword when initializing a `GelfFormatter`. You can also modify the `allowed_reserved_attrs` instance variable of an already initialized formatter. ##### Example ```python attrs = ["lineno", "module", "filename"] formatter = GelfFormatter(allowed_reserved_attrs=attrs) # or formatter.allowed_reserved_attrs = attrs logging.debug("starting application...") ``` ```text {"version": "1.1", "short_message": "starting application...", "timestamp": 1557346554.989846, "level": 6, "host": "my-server", "_lineno": 175, "_module": "myapp", "_filename": "app.py"} ``` You can optionally customize the name of these additional fields using a [`logging.Filter`](https://docs.python.org/3/library/logging.html#filter-objects) (see below). Similarily, you can choose to ignore additional attributes passed via the `extra` keyword argument. This can be usefull to e.g. not log keywords named `secret` or `password`. To do so, pass a list of names to the `ignored_attrs` keyword when initializing a `GelfFormatter`. You can also modify the `ignored_attrs` instance variable of an already initialized formatter. ##### Example But be aware: nested fields will be printed! Only the root level of keywords is filtered by the `ignored_attrs`. ```python attrs = ["secret", "password"] formatter = GelfFormatter(ignored_attrs=attrs) # or formatter.ignored_attrs = attrs logging.debug("app config", extra={"connection": "local", "secret": "verySecret!", "mysql": {"user": "test", "password": "will_be_logged"}}) ``` ```text {"version": "1.1", "short_message": "app config", "timestamp": 1557346554.989846, "level": 6, "host": "my-server", "_connection": "local", "_mysql": {"user": "test", "password": "will_be_logged"}} ``` #### Context Fields Having the ability to define a set of additional fields once and have them included in all log messages can be useful to avoid repetitive `extra` key/value pairs and enable contextual logging. Python's logging module provides several options to add context to a logger, among which we highlight the [`logging.LoggerAdapter`](https://docs.python.org/3/library/logging.html#loggeradapter-objects) and [`logging.Filter`](https://docs.python.org/3/library/logging.html#filter-objects). Between these we recommend a `logging.Filter`, which is simpler and can be attached directly to a [`logging.Handler`](https://docs.python.org/3/library/logging.html#handler-objects). A `logging.Filter` can therefore be used locally (on a [`logging.Logger`](https://docs.python.org/3/library/logging.html#logger-objects)) or globally (through `logging.basicConfig`). If you opt for a `LoggerAdapter` you'll need a `logging.Logger` to wrap. You can also use a `logging.Filter` to reuse/rename any of the reserved `logging.LogRecord` attributes. ##### Example ```python class ContextFilter(logging.Filter): def filter(self, record): # Add any number of arbitrary additional fields record.app = "my-app" record.app_version = "1.2.3" record.environment = os.environ.get("APP_ENV") # Reuse any reserved `logging.LogRecord` attributes record.file = record.filename record.line = record.lineno return True formatter = GelfFormatter() handler = logging.StreamHandler(sys.stdout) handler.setFormatter(formatter) handler.addFilter(ContextFilter()) logging.basicConfig(level=logging.DEBUG, handlers=[handler]) logging.info("hi", extra=dict(foo="bar")) ``` ```text {"version": "1.1", "short_message": "hi", "timestamp": 1557431642.189755, "level": 6, "host": "my-server", "_foo": "bar", "_app": "my-app", "_app_version": "1.2.3", "_environment": "development", "_file": "app.py", "_line": 159} ``` ## Pretty-Print Looking for a GELF log pretty-printer? If so, have a look at [gelf-pretty](https://github.com/joaodrp/gelf-pretty) :fire: ## Contributions This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please refer to our [contributing guide](CONTRIBUTING.md) for further information. %package help Summary: Development documents and examples for gelf-formatter Provides: python3-gelf-formatter-doc %description help ## Motivation There are several packages available providing *handlers* for the standard library logging module that can send application logs to [Graylog](https://www.graylog.org/) by TCP/UDP/HTTP ([py-gelf](https://pypi.org/project/pygelf/) is a good example). Although these can be useful, it's not ideal to make an application performance dependent on network requests just for the purpose of delivering logs. Alternatively, one can simply log to a file or `stdout` and have a collector (like [Fluentd](https://www.fluentd.org/)) processing and sending those logs *asynchronously* to a remote server (and not just to Graylog, as GELF can be used as a generic log format), which is a common pattern for containerized applications. In a scenario like this all we need is a GELF logging *formatter*. ## Features - Support for arbitrary additional fields; - Support for including reserved [`logging.LogRecord`](https://docs.python.org/3/library/logging.html#logrecord-attributes) attributes as additional fields; - Exceptions detection with traceback formatting; - Zero dependencies and tiny footprint. ## Installation ### With pip ```text $ pip install gelf-formatter ``` ### From source ```text $ python setup.py install ``` ## Usage Simply create a `gelfformatter.GelfFormatter` instance and pass it as argument to [`logging.Handler.setFormatter`](https://docs.python.org/3/library/logging.html#logging.Handler.setFormatter): ```python import sys import logging from gelfformatter import GelfFormatter formatter = GelfFormatter() handler = logging.StreamHandler(sys.stdout) handler.setFormatter(formatter) ``` Apply it globally with [`logging.basicConfig`](https://docs.python.org/3/library/logging.html#logging.basicConfig) to automatically format log records from third-party packages as well: ```python logging.basicConfig(level=logging.DEBUG, handlers=[handler]) ``` Alternatively, you can configure a local [`logging.Logger`](https://docs.python.org/3/library/logging.html#logging.Logger) instance through [`logging.Logger.addHandler`](https://docs.python.org/3/library/logging.html#logging.Logger.addHandler): ```python logger = logging.getLogger('my-app') logger.addHandler(handler) ``` That's it. You can now use the logging module as usual, all records will be formatted as GELF messages. ### Standard Fields The formatter will output all (non-deprecated) fields described in the [GELF Payload Specification (version 1.1)](http://docs.graylog.org/en/latest/pages/gelf.html#gelf-payload-specification): - `version`: String, always set to `1.1`; - `host`: String, the output of [`socket.gethostname`](https://docs.python.org/3/library/socket.html#socket.gethostname) at initialization; - `short_message`: String, log record message; - `full_message` (*optional*): String, formatted exception traceback (if any); - `timestamp`: Number, time in seconds since the epoch as a floating point; - `level`: Integer, *syslog* severity level. None of these fields can be ignored, renamed or overridden. #### Example ```python logging.info("Some message") ``` ```text {"version":"1.1","host":"my-server","short_message":"Some message","timestamp":1557342545.1067393,"level":6} ``` #### Exceptions The `full_message` field is used to store the traceback of exceptions. You just need to log them with [`logging.exception`](https://docs.python.org/3/library/logging.html#logging.exception). ##### Example ```python import urllib.request req = urllib.request.Request('http://www.pythonnn.org') try: urllib.request.urlopen(req) except urllib.error.URLError as e: logging.exception(e.reason) ``` ```text {"version": "1.1", "short_message": "[Errno -2] Name or service not known", "timestamp": 1557342714.0695107, "level": 3, "host": "my-server", "full_message": "Traceback (most recent call last):\n ...(truncated)... raise URLError(err)\nurllib.error.URLError: "} ``` ### Additional Fields The GELF specification allows arbitrary additional fields, with keys prefixed with an underscore. To include additional fields use the standard logging `extra` keyword. Keys will be automatically prefixed with an underscore (if not already). #### Example ```python logging.info("request received", extra={"path": "/orders/1", "method": "GET"}) ``` ```text {"version": "1.1", "short_message": "request received", "timestamp": 1557343604.5892842, "level": 6, "host": "my-server", "_path": "/orders/1", "_method": "GET"} ``` #### Reserved Fields By default the formatter ignores all [`logging.LogRecord` attributes](https://docs.python.org/3/library/logging.html#logrecord-attributes). You can however opt to include them as additional fields. This can be used to display useful information like the current module, filename, line number, etc. To do so, simply pass a list of `LogRecord` attribute names as value of the `allowed_reserved_attrs` keyword when initializing a `GelfFormatter`. You can also modify the `allowed_reserved_attrs` instance variable of an already initialized formatter. ##### Example ```python attrs = ["lineno", "module", "filename"] formatter = GelfFormatter(allowed_reserved_attrs=attrs) # or formatter.allowed_reserved_attrs = attrs logging.debug("starting application...") ``` ```text {"version": "1.1", "short_message": "starting application...", "timestamp": 1557346554.989846, "level": 6, "host": "my-server", "_lineno": 175, "_module": "myapp", "_filename": "app.py"} ``` You can optionally customize the name of these additional fields using a [`logging.Filter`](https://docs.python.org/3/library/logging.html#filter-objects) (see below). Similarily, you can choose to ignore additional attributes passed via the `extra` keyword argument. This can be usefull to e.g. not log keywords named `secret` or `password`. To do so, pass a list of names to the `ignored_attrs` keyword when initializing a `GelfFormatter`. You can also modify the `ignored_attrs` instance variable of an already initialized formatter. ##### Example But be aware: nested fields will be printed! Only the root level of keywords is filtered by the `ignored_attrs`. ```python attrs = ["secret", "password"] formatter = GelfFormatter(ignored_attrs=attrs) # or formatter.ignored_attrs = attrs logging.debug("app config", extra={"connection": "local", "secret": "verySecret!", "mysql": {"user": "test", "password": "will_be_logged"}}) ``` ```text {"version": "1.1", "short_message": "app config", "timestamp": 1557346554.989846, "level": 6, "host": "my-server", "_connection": "local", "_mysql": {"user": "test", "password": "will_be_logged"}} ``` #### Context Fields Having the ability to define a set of additional fields once and have them included in all log messages can be useful to avoid repetitive `extra` key/value pairs and enable contextual logging. Python's logging module provides several options to add context to a logger, among which we highlight the [`logging.LoggerAdapter`](https://docs.python.org/3/library/logging.html#loggeradapter-objects) and [`logging.Filter`](https://docs.python.org/3/library/logging.html#filter-objects). Between these we recommend a `logging.Filter`, which is simpler and can be attached directly to a [`logging.Handler`](https://docs.python.org/3/library/logging.html#handler-objects). A `logging.Filter` can therefore be used locally (on a [`logging.Logger`](https://docs.python.org/3/library/logging.html#logger-objects)) or globally (through `logging.basicConfig`). If you opt for a `LoggerAdapter` you'll need a `logging.Logger` to wrap. You can also use a `logging.Filter` to reuse/rename any of the reserved `logging.LogRecord` attributes. ##### Example ```python class ContextFilter(logging.Filter): def filter(self, record): # Add any number of arbitrary additional fields record.app = "my-app" record.app_version = "1.2.3" record.environment = os.environ.get("APP_ENV") # Reuse any reserved `logging.LogRecord` attributes record.file = record.filename record.line = record.lineno return True formatter = GelfFormatter() handler = logging.StreamHandler(sys.stdout) handler.setFormatter(formatter) handler.addFilter(ContextFilter()) logging.basicConfig(level=logging.DEBUG, handlers=[handler]) logging.info("hi", extra=dict(foo="bar")) ``` ```text {"version": "1.1", "short_message": "hi", "timestamp": 1557431642.189755, "level": 6, "host": "my-server", "_foo": "bar", "_app": "my-app", "_app_version": "1.2.3", "_environment": "development", "_file": "app.py", "_line": 159} ``` ## Pretty-Print Looking for a GELF log pretty-printer? If so, have a look at [gelf-pretty](https://github.com/joaodrp/gelf-pretty) :fire: ## Contributions This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please refer to our [contributing guide](CONTRIBUTING.md) for further information. %prep %autosetup -n gelf-formatter-0.2.1 %build %py3_build %install %py3_install install -d -m755 %{buildroot}/%{_pkgdocdir} if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi pushd %{buildroot} if [ -d usr/lib ]; then find usr/lib -type f -printf "\"/%h/%f\"\n" >> filelist.lst fi if [ -d usr/lib64 ]; then find usr/lib64 -type f -printf "\"/%h/%f\"\n" >> filelist.lst fi if [ -d usr/bin ]; then find usr/bin -type f -printf "\"/%h/%f\"\n" >> filelist.lst fi if [ -d usr/sbin ]; then find usr/sbin -type f -printf "\"/%h/%f\"\n" >> filelist.lst fi touch doclist.lst if [ -d usr/share/man ]; then find usr/share/man -type f -printf "\"/%h/%f.gz\"\n" >> doclist.lst fi popd mv %{buildroot}/filelist.lst . mv %{buildroot}/doclist.lst . %files -n python3-gelf-formatter -f filelist.lst %dir %{python3_sitelib}/* %files help -f doclist.lst %{_docdir}/* %changelog * Tue Jun 20 2023 Python_Bot - 0.2.1-1 - Package Spec generated