poundctl.tmpl - templates for poundctl.
The syntax of poundctl templates is modelled after and
mostly conforming to the specifications of the golang template module
(https://pkg.go.dev/text/template).
Templates are executed by applying them to a JSON object.
Annotations in a template refer to attributes of the object to control
execution and derive values to be displayed. Execution of the template walks
the structure and sets the cursor, represented by a period (called
dot), to the value at the current location in the object as execution
proceeds.
The input text for a template is as ASCII text is arbitrary
format. Actions -- data evaluations or control structures -- are
delimited by {{ and }}; all text outside actions is copied to
the output verbatim.
To aid in formatting template source code, if {{ is
followed immediately by a minus sign and white space, all trailing white
space is trimmed from the immediately preceding text. Similarly, if
}} is preceded by white space and a minus sign, all leading white
space is trimmed from the immediately following text. Notice that the
presence of the whitespace in these trim markers is mandatory: "{{-
3}}" trims the immediately preceding text and outputs "3",
while "{{-3}}" parses as an action containing the number -3.
Here is the list of actions. Arguments and pipelines
are evaluations of data, defined in detail in the corresponding sections
that follow.
- {{ }}
- Empty action is discarded. It may be useful to trim the preceding or
following whitespace, as in {{- -}} .
- {{/* a comment */}}
- Comments are discarded. They may span multiple lines of text. Comments do
not nest and must start immediately after the opening delimiter (with
optional dash and whitespace in between). A comment may be followed by any
action described below.
- Comments may be used to control trailing and leading whitespace as
well:
-
{{- a comment trimming the surrounding whitespace -}}
- {{pipeline}}
- Pipeline is evaluated, and the default textual representation of
its value is copied to the output.
- {{if pipeline}} T1 {{end}}
- If the value of the pipeline is empty, no output is generated;
otherwise, T1 is executed. The empty values are null,
false, numeric 0, empty string (""), array
([]), or object ({}). Dot is unaffected.
- {{if pipeline}} T1 {{else}} T0
{{end}}
- If the value of the pipeline is empty, T0 is executed; otherwise,
T1 is executed. Dot is unaffected.
- {{if pipeline}} T1 {{else if
pipeline}} T2 {{else}} T0
{{end}}
- A shortcut to simplify writing the if-else chains. Equivalent to (newlines
added for readability):
-
{{if pipeline }}
T1
{{else -}}
{{if pipeline }}
T2
{{else}}
T0
{{end}}
{{end}}
- {{range pipeline}} T1 {{end}}
- The value of pipeline must be an object or array. If it is of
length zero, nothing is output. Otherwise, dot is set to the successive
elements of the array or object and T1 is executed. For objects,
the elements will be visited in sorted key order.
- {{range pipeline}} T1 {{else}} T0
{{end}}
- Same as above, except that if the value of the pipeline is of
length zero, T0 is executed with dot unaffected.
- Within the {{range}} action, the following two keywords may
appear:
- {{break}}
- The innermost {{range pipeline}} loop is ended early,
stopping the current iteration and bypassing all remaining
iterations.
- {{continue}}
- The current iteration of the innermost {{range
pipeline}} loop is stopped, and the loop starts the next
iteration.
- {{define "name"}} text
{{end}}
- The text is collected and stored for the further use as template
with the given name. It can be invoked using the
{{template}} action (see below).
- {{template "name"}}
- The template with the specified name (see the {{define}}
above) is executed with dot set to null.
- {{template "name"
value}}
- The template with the specified name (see the {{define}}
above) is executed with dot set to value.
- {{block "name" pipeline}}
T1 {{end}}
- A block is shorthand for defining a template
-
{{define "name"}} T1 {{end}}
- and then executing it in place
-
{{template "name" pipeline}}
- {{with pipeline}} T1 {{end}}
- If the value of the pipeline is empty, no output is generated;
otherwise, dot is set to the value of the pipeline and T1 is
executed.
- {{with pipeline}} T1 {{else}} T0
{{end}}
- Same as above, but if the value of the pipeline is empty, T0
is executed with dot unchanged.
A pipeline is a series of one or more commands
delimited by pipe sign (|). Each command is either an argument
or a function call, in form:
func arg1 arg2...
where func is the name of one of the built-in functions
discussed below.
Pipelines are executed from left to right, with the result of the
previous command implicitly added to the list of arguments of each
subsequent command. For example, the pipeline
.attr | eq $x
is equivalent to
eq $x .attr
i.e. it calls the built-in function eq with two arguments:
the value of the variable x and attribute attr of the cursor
value.
The following built-in functions are defined:
- and A1 A2
- Evaluates to true if pipelines A1 and A2 both
evaluate to true. Notice, that there is no boolean shortcut
evaluation: both pipelines are evaluated prior to calling and.
- or A1 A2
- Evaluates to true if at least one of the pipelines A1 and
A2 evaluates to true. Notice, that there is no boolean
shortcut evaluation: both pipelines are evaluated prior to calling
or.
- index A1
A2...
- Returns the result of indexing its first argument by the following
arguments. Thus, if . is an array, then:
-
index . 5
- evaluates to its fifth element (.[5]).
- len A1
- Returns the integer length of its argument.
- not A1
- Returns true if its argument evaluates to false.
- eq A1 A2
- Returns true if both its arguments are equal. This applies only if
both A1 and A2 are numeric or if they both are strings.
- ne A1 A2
- Returns true if its arguments (both must be numeric or strings) are
not equal.
- lt A1 A2
- Returns true if A1 is numerically less than A2.
- le A1 A2
- Returns true if A1 is numerically less than or equal to
A2.
- gt A1 A2
- Returns true if A1 is numerically greater than
A2.
- ge A1 A2
- Returns true if A1 is numerically greater than or equal to
A2.
- even A1
- Returns true if A1, which must evaluate to an integer value,
is divisible by 2.
- printf FMT
A1...
- Implements the printf(3) function. FMT must evaluate to a
string. Rest of arguments is interpreted according to the conversion
specifications in FMT. The result is a formatted string.
- In addition to the standard conversion specifications described in
printf(3), the "%v" specifier is implemented: it formats
its argument in the best way, depending on its actual type.
- typeof
A1
- Evaluates to the type of its argument, one of: null, bool,
number, integer, string, array,
object.
- exists A1
A2
- A1 must evaluate to an object and A2 to string. The function
evaluates to true if the attribute A2 is present in
A1.
- add A1
A2...
- Returns the sum of its arguments.
- sub A1 A2
- Returns the difference A1 - A2.
- mul A1 A2
- Multiplies A1 by A2.
- div A1 A2
- Divides A1 by A2.
Variables (referred to as $name) can be defined in
range and with actions. For range, the syntax is:
{{range $index, $element = pipeline}} T1 {{end}}
where index and element are arbitrary variable
names. When executing this action, during each iteration $index and
$element are set to the index (attribute name) and value of each
successive element. Dot remains unaffected.
For with, the syntax is:
{{with $var = pipeline}} T1 {{end}}
Pipeline is evaluated, its result is assigned to
$var and the T1 block is executed with dot unchanged.
A variable's scope extends to the end action of the control
structure (with or range) in which it is declared. This
includes any nested statements that may appear in between.
Depending on the request issued by poundctl, the invoked
template can receive as its argument (dot) an object of the following
types: full listing, listener, service, or backend.
Since there is no explicit indication of the object type being
passed, templates normally use heuristics based on the presence or absence
of certain attribute to deduce the object type in question. The recommended
approach is described in the following pseudo-code fragment:
{{if exists . "listeners" }}
{{/* This is a full listing, as requested by poundctl list. */}}
...
{{else if exists . "services"}}
{{/* Single listener, as requested by poundctl list /L.
Notice that this attribute is present in the full listing as
well, so presence of "listeners" should be checked first. */}}
...
{{else if exists . "backends"}}
{{/* Single service, as requested by poundctl list /L/S. */}}
...
{{else}}
{{/* Backend listing (poundctl list /L/S/B) */}}
...
{{end}}
Structures of each object are discussed in subsections that
follow.
A full listing contains the following attributes:
- listeners
- An array of listener objects. See below for a description.
- services
- An array of service objects, representing services defined in the
global scope of the pound configuration file.
- pid
- PID of the running pound daemon.
- version
- Pound version number (string).
- workers
- Workers statistics. This is a JSON object with the following
attributes:
- active
- Number of active threads.
- count
- Number of threads currently running.
- max
- Maximum number of threads.
- min
- Minimum number of threads.
- timeout
- Thread idle timeout.
- queue_len
- Number of incoming HTTP requests in the queue (integer).
- timestamp
- Current time on the server, formatted as ISO 8601 date-time with
microsecond precision, e.g.: "2023-01-05T22:43:18.071559".
A listener object represents a single HTTP or HTTPS
listener in pound configuration. It has the following attributes:
- address
- String. Address of this listener. A string formatted as
"IP:PORT" for IPv4 and IPv6 addresses or
containing socket file name, for UNIX sockets.
- protocol
- String. Protocol used: either http or https.
- services
- Array of service objects representing services defined in this
listener. See below for the definition of a service object.
- enabled
- Boolean. Whether this listener is enabled or not.
- nohttps11
- Integer. Value of the NoHTTPS11 configuration statement for
this listener. One of: 0, 1, 2.
A service object describes a single service.
- name
- String. Symbolic name of this service.
- enabled
- Boolean. Whether this service is enabled or not.
- session_type
- String. Name of the session handling algorithm for this service.
One of: IP, BASIC, URL, PARM, COOKIE,
HEADER.
- sessions
- List of active sessions in this service. Each session is represented as
object with the following attributes:
- key
- String. Session key.
- backend
- Integer. Number of the backend assigned to handle requests with
this session.
- expire
- Timestamp. Expiration time of this session, with microsecond
precision.
- backends
- List of backends defined for this service.
- emergency
- Emergency backend object, or null if no such backend is
defined.
The following attributes are always present in each backend
object:
- alive
- Boolean. Whether or not this backend is alive.
- conn_to
- Integer. Connection timeout for this backend (seconds).
- enabled
- Boolean. Whether or not this backend is enabled.
- io_to
- Integer. I/O timeout for this backend (seconds).
- priority
- Integer in range 0-9. Priority value assigned to this backend.
- protocol
- String. Protocol used by this backend: either http or
https.
- type
- String. Backend type. One of: acme, backend,
control, redirect.
- ws_to
- Integer Websocket timeout (seconds).
Depending on the backend type, the following attributes may be
present:
- acme
- path
- String. Directory where ACME challenges are stored.
- backend
- redirect
- url
- String. URL to redirect to.
- code
- Integer. HTTP code for redirection responses. One of: 301, 302,
307.
- redir_req
- Boolean. Whether to append the original request path to the
resulting location.
If backend statistics is enabled (see BackendStats in
pound(8)), the stats object will be present, with the
following attributes:
- request_count
- Total number of requests processed by this backend.
- request_time_avg
- Average time per request, in nanoseconds.
- request_time_stddev
- Standard deviation of the above.
Report bugs to <gray@gnu.org>. You may also use github issue
tracker at https://github.com/graygnuorg/pound/issues.
Copyright © 2023-2025 Sergey Poznyakoff
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.