Execute external script or program
==================================

The `external-executable` event handler can be configured to call an external
script or program based on an event.

..  contents:: :local:


Introduction
------------

This event handler will call an external script or executable.
At the end of the execution it will emit the event `20053` with the following details:

* `command` - the actual command that was called
* `exit_code`` - the exit code
* `output` - full standard output generated while calling the executable or script.
* `error` - full standard error generated while calling the executable or script.
* `output_log` - the first 200 characters from the standard output, sanitized to be included in logs.
* `error_log` - the first 200 characters from the standard error, sanitized to be included in logs.

The following environment variables are available to the executed script or
program:

:EVENT: ID of the event for which it was called.
:HANDLER_UUID: UUID of this event handler.
:COMPONENT_UUID: UUID of the SFTPPlus component which has created the event.
:TIMESTAMP: Unix timestamp when this event was generated.
:PEER: Associated IP and PORT
:USER: Associated user/account.
:DATA_*:
    Data members of this event.
    For example `DATA_REAL_PATH` or `DATA_DETAILS`.

The following environment variables are copied from the main SFTPPlus process:

* `PATH`
* `PWD` - Linux and macOS only
* `SystemDrive` - Windows only
* `SystemRoot` - Windows only

SFTPPlus will only call a maximum of 3 external commands in parallel.
External commands that need to be triggered for the generated events are queued and executed one after another.
This is done to prevent extreme usage of the OS resources.

Since you can receive 1000 files in a short period,
launching 1000 operating system sub-processes at the same time can result in
blocking the whole operating system by using too much memory or too many processes.
For example,
with an external executable using 100MB of memory,
calling 10 concurrent such jobs would result in 1GB of extra memory usage.

The `external-executable` event handler is designed to be used as a notification mechanism
or for calling external commands that are fast and have low-memory usage.
The event handler is not designed to operate as a sub-process manager,
nor for the handling of long-running or extensive memory usage processes.

If your external executable uses more than 100MB of memory or takes longer than 10 seconds to operate,
consider redesigning your system.
For example reduce the run duration or reduce the run frequency by filtering events with the `target` and `data_filter` options).

.. include:: /configuration-events/events-commons.include.rst


executable_path
---------------

:Default value: ''
:Optional: No
:Values: * Local filesystem path.
:From version: 3.47.0
:Description:
    Local filesystem path to the executable.


executable_arguments
--------------------

:Default value: ``{data.real_path}``
:Optional: Yes
:Values: * Plain text.
         * Variable expression.
:From version: 3.47.0
:Description:
    This configuration defines the arguments used to call the executable.

    Make sure the arguments that might contain spaces are enclosed in quotes.

    .. include:: /configuration/event-context-variables.rst.include


executable_output_format
------------------------

:Default value: `text`
:Optional: Yes
:Values: * `text`
         * `json`
:From version: 4.32.0
:Description:
    This configuration defines the expected output generated by this command.

    Default option is `text` and the output will be handled without any additional processing.
    The standard output value generated by the call will be available inside the event as ``data.output``.

    When this is configured as `json` the output is expected to be a valid JSON object.
    The JSON object will be available inside the event at ``data.output``.

    For example, parts of the following JSON object can be accesses as ``data.output.member2.other``::

        {"member1": "value1", "member2": {"other": "object", "not": "supported"}


executable_timeout
------------------

:Default value: 30
:Optional: Yes
:Values: * Number
:From version: 3.47.0
:Description:
    Number of seconds to allow for the external process to execute before
    forcefully closing it.

    A configured value must be equal to or greater than 1.


concurrent_processes
--------------------

:Default value: 2
:Optional: Yes
:Values: * Number
:From version: 3.47.0
:Description:
    The maximum number of concurrent processes to execute at the same time.

    When the event handler is required to handle more events, the remaining
    events are placed in the queue and executed as soon as possible, making
    sure that only the configured number or processes are active at the same
    time.

    A configured value must be equal to or greater than 1.

    We recommend setting this based on the number of available CPUs.
