# Python code in external files

You can extend and customize AxoSyslog easily by writing [destinations](../../docs/axosyslog-core/chapter-destinations/python-destination/index.md), [parsers](../../docs/axosyslog-core/chapter-parsers/python-parser/index.md), [template functions](../../docs/axosyslog-core/chapter-destinations/python-destination/index.md#template-function-python), and [sources](../../docs/axosyslog-core/chapter-sources/python-source/index.md) in Python.

Instead of writing Python code into your AxoSyslog configuration file, you can store the Python code for your Python object in an external file. That way, it is easier to write, maintain, and debug the code. You can store the Python code in any directory in your system, but make sure to include it in your Python path.

When referencing a Python class from an external file in the `class()` option of a Python block in the AxoSyslog configuration file, the class name must include the name of the Python file containing the class, without the path and the .py extension. For example, if the MyDestination class is available in the `/etc/syslog-ng/etc/pythonexample.py` file, use `class("pythonexample.MyDestination")`:
```
 
       destination d_python_to_file {
            python(
                class("pythonexample.MyDestination")
            );
        };
        log {
            source(src);
            destination(d_python_to_file);
        };
    
```

Note

Starting with 3.26, AxoSyslog assigns a persist name to Python sources and destinations. The persist name is generated from the class name. If you want to use the same Python class multiple times in your AxoSyslog configuration, add a unique `persist-name()` to each source or destination, otherwise AxoSyslog will not start. For example:
```
 
       log {
            source { python(class(PyNetworkSource) options("port" "8080") persist-name("<unique-string>); };
            source { python(class(PyNetworkSource) options("port" "8081")); };
        };
    
```

Alternatively, you can include the following line in the Python package: `@staticmethod generate_persist_name`. For example:
```
 
       from syslogng import LogSource
          class PyNetworSource(LogSource):
            @staticmethod
            def generate_persist_name(options):
                return options["port"]
            def run(self):
                pass
            def request_exit(self):
                pass
    
```

If you store the Python code in a separate Python file and only include it in the AxoSyslog configuration file, make sure that the PYTHONPATH environment variable includes the path to the Python file, and export the PYTHON_PATH environment variable. For example, if you start AxoSyslog manually from a terminal and you store your Python files in the `/opt/syslog-ng/etc` directory, use the following command: `export PYTHONPATH=/opt/syslog-ng/etc`.

In production, when AxoSyslog starts on boot, you must configure your startup script to include the Python path. The exact method depends on your operating system. For recent Red Hat Enterprise Linux, Fedora, and CentOS distributions that use systemd, the `systemctl` command sources the `/etc/sysconfig/syslog-ng` file before starting AxoSyslog. (On openSUSE and SLES, `/etc/sysconfig/syslog` file.) Append the following line to the end of this file: `PYTHONPATH="<path-to-your-python-file>"`, for example, `PYTHONPATH="/opt/syslog-ng/etc"`.

To help debugging and troubleshooting your Python code, you can send log messages to the `internal()` source of AxoSyslog. For details, see [Logging from your Python code](../../docs/axosyslog-core/chapter-configuration-file/python-code-logging/index.md).

Last modified July 2, 2023: [Change highlight mode of code examples (2f8a9593)](<https://github.com/axoflow/axosyslog-core-docs/commit/2f8a95937c6498193e7168ce8b0dc831e9f0f8ad>)