API module#

New in version 1.0.0.

Module provides HTTP RESTful interface for accessing in JSON format basic information about a web server instance, as well as metrics of client connections, shared memory zones, DNS queries, HTTP requests, HTTP responses cache, TCP/UDP sessions of stream_core module, and zones of http limit_conn, stream limit_conn, limit_req and http upstream modules.

The API accepts GET and HEAD HTTP requests; other request methods cause an error:

{
    "error": "MethodNotAllowed",
    "description": "The POST method is not allowed for the requested API element \"/\"."
}

Directives#

api#

Syntax:

api path;

Default:

Context:

location

Enables HTTP RESTful interface in location.

path parameter is mandatory and works similar to the alias directive, but operates over API tree, rather than filesystem hierarchy.

When specified in a prefix location:

location /stats/ {
        api /status/http/server_zones/;
}

the part of request URI matching particular prefix location /stats/ will be replaced by the path /status/http/server_zones/ in the directive parameter. For example, on a request of /stats/foo/ the /status/http/server_zones/foo/ API element will be accessed.

Also it’s possible to use variables: api /status/$module/server_zones/$name/ and the directive can also be specified inside a regexp location:

location ~^/api/([^/]+)/(.*)$ {
        api /status/http/$1_zones/$2;
}

here, similar to alias, parameter defines the whole path to the API element. E.g., from /api/location/bar/data/ the following positional variables will be populated:

$1 = "location"
$2 = "bar/data/"

which results after interpolation in /status/http/location_zones/bar/data API request.

Overall, it serves for precise configuration of API access rights, e.g.:

location /status/ {
        api /status/;

        allow 127.0.0.1;
        deny  all;
}

Or:

location /blog/requests/ {
        api /status/http/server_zones/blog/requests/;

        auth_basic           "blog";
        auth_basic_user_file conf/htpasswd;
}

api_config_files#

Syntax:

api_config_files on | off;

Default:

off

Context:

location

Enables or disables the config_files object, which enumerates the contents of Angie config files, in the /status/angie/ API section. For example, with this configuration:

location /status/ {
    api /status/;
    api_config_files on;
}

A query to /status/angie/ returns approximately this:

{
    "version":"1.3.0",
    "address":"192.168.16.5",
    "generation":1,
    "load_time":"2023-09-18T12:58:39.789Z",
    "config_files": {
        "/etc/angie/angie.conf": "...",
        "/etc/angie/mime.types": "..."
    }
}

By default, the object is disabled because the config files can contain extra sensitive, confidential details.

Metrics#

Angie exposes usage metrics in the /status/ section of the API; you can make it accessible by defining a respective location. Full access:

location /status/ {
    api /status/;
}

Subtree access, already discussed earlier:

location /stats/ {
    api /status/http/server_zones/;
}

Example configuration#

Configured with location /status/, resolver, http upstream, http server, location, cache, limit_conn in http and limit_req zones:

http {

    resolver 127.0.0.53 status_zone=resolver_zone;
    proxy_cache_path /var/cache/angie/cache keys_zone=cache_zone:2m;
    limit_conn_zone $binary_remote_addr zone=limit_conn_zone:10m;
    limit_req_zone $binary_remote_addr zone=limit_req_zone:10m rate=1r/s;

    upstream upstream {
        zone upstream 256k;
        server backend.example.com service=_example._tcp resolve max_conns=5;
       keepalive 4;
    }

    server {
        server_name www.example.com;
        listen 443 ssl;

        status_zone http_server_zone;
        proxy_cache cache_zone;

        access_log /var/log/access.log main;

        location / {
            root /usr/share/angie/html;
            status_zone location_zone;
            limit_conn limit_conn_zone 1;
            limit_req zone=limit_req_zone burst=5;
        }
        location /status/ {
            api /status/;

            allow 127.0.0.1;
            deny all;
        }

    }
}

Responds to curl https://www.example.com/status/ with the following JSON:

JSON tree
{
    "angie": {
        "version":"1.3.0",
        "address":"192.168.16.5",
        "generation":1,
        "load_time":"2023-09-19T12:58:39.789Z"
    },

    "connections": {
        "accepted":2257,
        "dropped":0,
        "active":3,
        "idle":1
    },

    "slabs": {
        "cache_zone": {
            "pages": {
                "used":2,
                "free":506
            },

            "slots": {
                "64": {
                    "used":1,
                    "free":63,
                    "reqs":1,
                    "fails":0
                },

                "512": {
                    "used":1,
                    "free":7,
                    "reqs":1,
                    "fails":0
                }
            }
        },

        "limit_conn_zone": {
            "pages": {
                "used":2,
                "free":2542
            },

            "slots": {
                "64": {
                    "used":1,
                    "free":63,
                    "reqs":74,
                    "fails":0
                },

                "128": {
                    "used":1,
                    "free":31,
                    "reqs":1,
                    "fails":0
                }
            }
        },

        "limit_req_zone": {
            "pages": {
                "used":2,
                "free":2542
            },

            "slots": {
                "64": {
                    "used":1,
                    "free":63,
                    "reqs":1,
                    "fails":0
                },

                "128": {
                    "used":2,
                    "free":30,
                    "reqs":3,
                    "fails":0
                }
            }
        }
    },

    "http": {
        "server_zones": {
            "http_server_zone": {
                "ssl": {
                    "handshaked":4174,
                    "reuses":0,
                    "timedout":0,
                    "failed":0
                },

                "requests": {
                    "total":4327,
                    "processing":0,
                    "discarded":8
                },

                "responses": {
                    "200":4305,
                    "302":12,
                    "404":4
                },

                "data": {
                    "received":733955,
                    "sent":59207757
                }
            }
        },

        "location_zones": {
            "location_zone": {
                "requests": {
                    "total":4158,
                    "discarded":0
                },

                "responses": {
                    "200":4157,
                    "304":1
                },

                "data": {
                    "received":538200,
                    "sent":177606236
                }
            }
        },
        "caches": {
            "cache_zone": {
                "size":0,
                "cold":false,
                "hit": {
                    "responses":0,
                    "bytes":0
                },

                "stale": {
                    "responses":0,
                    "bytes":0
                },

                "updating": {
                    "responses":0,
                    "bytes":0
                },

                "revalidated": {
                    "responses":0,
                    "bytes":0
                },

                "miss": {
                    "responses":0,
                    "bytes":0,
                    "responses_written":0,
                    "bytes_written":0
                },

                "expired": {
                    "responses":0,
                    "bytes":0,
                    "responses_written":0,
                    "bytes_written":0
                },

                "bypass": {
                    "responses":0,
                    "bytes":0,
                    "responses_written":0,
                    "bytes_written":0
                }
            }
        },

        "limit_conns": {
            "limit_conn_zone": {
                "passed":73,
                "skipped":0,
                "rejected":0,
                "exhausted":0
            }
        },

        "limit_reqs": {
            "limit_req_zone": {
                "passed":54816,
                "skipped":0,
                "delayed":65,
                "rejected":26,
                "exhausted":0
            }
        },

        "upstreams": {
            "upstream": {
                "peers": {
                    "192.168.16.4:80": {
                        "server":"backend.example.com",
                        "service":"_example._tcp",
                        "backup":false,
                        "weight":5,
                        "state":"up",
                        "selected": {
                            "current":2,
                            "total":232
                        },

                        "max_conns":5,
                        "responses": {
                            "200":222,
                            "302":12
                        },

                        "data": {
                            "sent":543866,
                            "received":27349934
                        },

                        "health": {
                            "fails":0,
                            "unavailable":0,
                            "downtime":0
                        },

                        "sid":"<server_id>"
                    }
                },

                "keepalive":2
            }
        }
    },

    "resolvers": {
        "resolver_zone": {
            "queries": {
                "name":442,
                "srv":2,
                "addr":0
            },

            "responses": {
                "success":440,
                "timedout":1,
                "format_error":0,
                "server_failure":1,
                "not_found":1,
                "unimplemented":0,
                "refused":1,
                "other":0
            }
        }
    }
}

Each JSON branch can be requested separately with the request constructed accordingly, e.g.:

$ curl https://www.example.com/status/angie
$ curl https://www.example.com/status/connections
$ curl https://www.example.com/status/slabs
$ curl https://www.example.com/status/slabs/<zone>/slots
$ curl https://www.example.com/status/slabs/<zone>/slots/64
$ curl https://www.example.com/status/http/
$ curl https://www.example.com/status/http/server_zones
$ curl https://www.example.com/status/http/server_zones/<http_server_zone>
$ curl https://www.example.com/status/http/server_zones/<http_server_zone>/ssl

Server status#

/status/angie#

{
    "version": "1.3.0",
    "address": "192.168.16.5",
    "generation": 1,
    "load_time": "2023-09-18T16:15:43.805Z"
    "config_files": {
        "/etc/angie/angie.conf": "...",
        "/etc/angie/mime.types": "..."
    }
}

version

String; version of the running Angie web server

address

String; the address of the server that accepted API request

generation

Number; total number of configuration reloads since last start

load_time

String; time of the last configuration reload, formatted as ISO 8601 with millisecond resolution

config_files

Object; its members are absolute pathnames of all currently loaded Angie configuration files, and their values are string representations of the files’ contents, for example:

{
    "/etc/angie/angie.conf": "server {\n  listen 80;\n  server_name localhost;\n\n}\n"
}

Caution

The config_files object is available in /status/angie/ only if the api_config_files directive is enabled.

version

String; version of the running Angie web server

build

String; particular build name when it specified during compilation

address

String; the address of the server that accepted API request

generation

Number; total number of configuration reloads since last start

load_time

String; time of the last configuration reload, formatted as ISO 8601 with millisecond resolution

Connections global metrics#

/status/connections#

{
  "accepted": 2257,
  "dropped": 0,
  "active": 3,
  "idle": 1
}

accepted

Number; the total number of accepted client connections

dropped

Number; the total number of dropped client connections

active

Number; the current number of active client connections

idle

Number; the current number of idle client connections

Slab allocator metrics of shared memory zones#

Usage statistics of configured shared memory zones, such as: limit_conn, limit_req, HTTP cache

limit_conn_zone $binary_remote_addr zone=limit_conn_zone:10m;
limit_req_zone $binary_remote_addr zone=limit_req_zone:10m rate=1r/s;
proxy_cache cache_zone;

/status/slabs/<zone>#

where <zone> is the name of any configured status_zone shared memory zone that uses slab allocator

{
  "pages": {
    "used": 2,
    "free": 506
  },

  "slots": {
    "64": {
      "used": 1,
      "free": 63,
      "reqs": 1,
      "fails": 0
  }
}

pages

Object; memory pages statistics

    used

Number; the number of currently used memory pages

    free

Number; the number of currently free memory pages

slots

Object; memory slots statistics for each slot size. The slots object contains fields for requested memory slot sizes (e.g. 8, 16, 32, etc., up to half of the page size)

    used

Number; the number of currently used memory slots of specified size

    free

Number; the number of currently free memory slots of specified size

    reqs

Number; the total number of attempts to allocate memory slot of specified size

    fails

Number; the number of unsuccessful attempts to allocate memory slot of specified size

Resolver#

The statistics collection is enabled by specifying the zone name in the status_zone=<name> (status_zone) parameter of the resolver directive.

resolver 127.0.0.53 status_zone=resolver_zone;

/status/resolvers/<zone>#

where <zone> is the name of any shared memory zone that collects resolver statistics

{
  "queries": {
    "name": 442,
    "srv": 2,
    "addr": 0
  },

  "responses": {
    "success": 440,
    "timedout": 1,
    "format_error": 0,
    "server_failure": 1,
    "not_found": 1,
    "unimplemented": 0,
    "refused": 1,
    "other": 0
  }
}

queries

Object; queries statistics

    name

Number; the number of queries to resolve names to addresses (A and AAAA types queries)

    srv

Number; the number of queries to resolve services to addresses (SRV type queries)

    addr

Number; the number of queries to resolve addresses to names (PTR type queries)

responses

Object; responses statistics

    success

Number; the number of successful responses

    timedout

Number; the number of timed out queries

    format_error

Number; the number responses with code 1 (Format error)

    server_failure

Number; the number responses with code 2 (Server failure)

    not_found

Number; the number responses with code 3 (Name Error)

    unimplemented

Number; the number responses with code 4 (Not Implemented)

    refused

Number; the number responses with code 5 (Refused)

    other

Number; the number of queries completed with other non-zero code

The response codes are described in RFC 1035, section 4.1.1.

HTTP server and location#

The status_zone <zone> (status_zone) directive specified in the server context enables the collection of statistics in the specified server zone. Object ssl is filled up with data when server is configured with listen ssl;

server {
        ...
        status_zone http_server_zone;

/status/http/server_zones/<zone>#

where <zone> is the name of any shared memory zone that collects server statistics

"ssl": {
  "handshaked": 4174,
  "reuses": 0,
  "timedout": 0,
  "failed": 0
},

"requests": {
  "total": 4327,
  "processing": 0,
  "discarded": 0
},

"responses": {
  "200": 4305,
  "302": 6,
  "304": 12,
  "404": 4
},

"data": {
  "received": 733955,
  "sent": 59207757
}

ssl

Object; SSL statistics

    handshaked

Number; the total number of successful SSL handshakes

    reuses

Number; the total number of session reuses during SSL handshake

    timedout

Number; the total number of timed out SSL handshakes

    failed

Number; the total number of failed SSL handshakes

requests

Object; requests statistics

    total

Number; the total number of client requests

    processing

Number; the number of currently being processed client requests

    discarded

Number; the total number of client requests completed without sending a response

responses

Object; responses statistics

    <code>

Number; a non-zero number of responses with status <code> (100-599)

    xxx

Number; a non-zero number of responses with other status codes

data

Object; data statistics

    received

Number; the total number of bytes received from clients

    sent

Number; the total number of bytes sent to clients

The status_zone <zone> (status_zone) directive, specified in location and if in location contexts enables the collection of statistics in the specified location zone. The special value off disables statistics collection in nested location blocks. location branch never includes ssl object and requests/processing metric

location / {
        root /usr/share/angie/html;
        status_zone location_zone;
}

/status/http/location_zones/<zone>#

{
  "requests": {
    "total": 4158,
    "discarded": 0
  },

  "responses": {
    "200": 4157,
    "304": 1
  },

  "data": {
    "received": 538200,
    "sent": 177606236
  }
}

Stream server#

The status_zone <zone> (status_zone) directive specified in the server context enables the collection of statistics in the specified server zone. Object ssl is filled up with data when server is configured with listen ssl;

server {
        ...
        status_zone stream_server_zone;

/status/stream/server_zones/<zone>#

where <zone> is the name of any shared memory zone that collects server statistics

{
  "ssl": {
    "handshaked": 24,
    "reuses": 0,
    "timedout": 0,
    "failed": 0
  },

  "connections": {
    "total": 24,
    "processing": 1,
    "discarded": 0
  },

  "sessions": {
    "success": 24,
    "invalid": 0,
    "forbidden": 0,
    "internal_error": 0,
    "bad_gateway": 0,
    "service_unavailable": 0
  },

  "data": {
    "received": 2762947,
    "sent": 53495723
  }
}

ssl

Object; SSL statistics

    handshaked

Number; the total number of successful SSL handshakes

    reuses

Number; the total number of session reuses during SSL handshake

    timedout

Number; the total number of timed out SSL handshakes

    failed

Number; the total number of failed SSL handshakes

connections

Object; connections statistics

    total

Number; the total number of client connections

    processing

Number; the number of currently being processed client connections

    discarded

Number: the total number of client connections completed without creating a session

sessions

Object; sessions statistics

    success

Number; the number of sessions completed with code 200, which means successful completion

    invalid

Number; the number of sessions completed with code 400, which happens when client data could not be parsed, e.g. the PROXY protocol header

    forbidden

Number; the number of sessions completed with code 403, when access was forbidden, for example, when access is limited for certain client addresses

    internal_error

Number; the number of sessions completed with code 500, the internal server error

    bad_gateway

Number; the number of sessions completed with code 502, bad gateway, for example, if an upstream server could not be selected or reached

    service_unavailable

Number; the number of sessions completed with code 503, service unavailable, for example, when access is limited by the number of connections

data

Object; data statistics

    received

Number; the total number of bytes received from clients

    sent

Number; the total number of bytes sent to clients

/status/stream/upstreams/<upstream>#

Here, <upstream> is the name of an upstream that is configured with a zone directive.

{
    "peers": {
        "192.168.16.4:1935": {
            "server": "backend.example.com",
            "service": "_example._tcp",
            "backup": false,
            "weight": 5,
            "state": "up",
            "selected": {
                "current": 2,
                "total": 232
            },

            "max_conns": 5,
            "data": {
                "sent": 543866,
                "received": 27349934
            },

            "health": {
                "fails": 0,
                "unavailable": 0,
                "downtime": 0
            }
        }
    }
}

peers

Object; contains the metrics of the upstream’s peers as subobjects whose names are canonical representations of the peers’ addresses. Members of each subobject:

    server

String; address set by the server directive

    service

String; service name, if set by server directive

    backup

Boolean; true for backup server

    weight

Number; the weight of the peer

    state

String; current state of the peer — up, down, or unavailable (the last one means max_fails was reached)

    selected

Object; the peer’s selection metrics

        current

Number; current connections to the peer

        total

Number; total connections forwarded to the peer

        last

String; the peer’s last selection time, formatted as ISO 8601

    max_conns

Number; maximum number of simultaneous active connections to the peer, if set

    data

Object; data transfer metrics

        received

Number; total bytes received from the peer

        sent

Number; total bytes sent to the peer

    health

Object; peer health metrics

        fails

Number; total failed attempts to reach the peer

        unavailable

Number; times the peer became unavailable due to reaching the max_fails

        downtime

Number; total time (in milliseconds) that the peer was unavailable for selection

        downstart

String; last time the peer became unavailable, formatted as ISO 8601

HTTP caches#

proxy_cache cache_zone;

/status/http/caches/<cache>#

For each zone configured with proxy_cache, the following data is stored:

{
  "name_zone": {
    "size": 0,
    "cold": false,
    "hit": {
      "responses": 0,
      "bytes": 0
    },

    "stale": {
      "responses": 0,
      "bytes": 0
    },

    "updating": {
      "responses": 0,
      "bytes": 0
    },

    "revalidated": {
      "responses": 0,
      "bytes": 0
    },

    "miss": {
      "responses": 0,
      "bytes": 0,
      "responses_written": 0,
      "bytes_written": 0
    },

    "expired": {
      "responses": 0,
      "bytes": 0,
      "responses_written": 0,
      "bytes_written": 0
    },

    "bypass": {
      "responses": 0,
      "bytes": 0,
      "responses_written": 0,
      "bytes_written": 0
    }
  }
}

size

Number; the current size of the cache

max_size

Number; configured limit on the maximum size of the cache

cold

Boolean; true while the cache loader loads data from disk

hit

Object; statistics of valid cached responses (proxy_cache_valid)

    responses

Number; the total number of responses read from the cache

    bytes

Number; the total number of bytes read from the cache

stale

Object; statistics of expired responses taken from the cache (proxy_cache_use_stale)

    responses

Number; the total number of responses read from the cache

    bytes

Number; the total number of bytes read from the cache

updating

Object; statistics of expired responses taken from the cache while responses were being updated (proxy_cache_use_stale updating)

    responses

Number; the total number of responses read from the cache

    bytes

Number; the total number of bytes read from the cache

revalidated

Object; statistics of expired and revalidated responses taken from the cache (proxy_cache_revalidate)

    responses

Number; the total number of responses read from the cache

    bytes

Number; the total number of bytes read from the cache

miss

Object; statistics of responses not found in the cache

    responses

Number; the total number of corresponding responses

    bytes

Number; the total number of bytes read from the proxied server

    responses_written

Number; the total number of responses written to the cache

    bytes_written

Number; the total number of bytes written to the cache

expired

Object; statistics of expired responses not taken from the cache

    responses

Number; the total number of corresponding responses

    bytes

Number; the total number of bytes read from the proxied server

    responses_written

Number; the total number of responses written to the cache

    bytes_written

Number; the total number of bytes written to the cache

bypass

Object; statistics of responses not looked up in the cache (proxy_cache_bypass)

    responses

Number; the total number of corresponding responses

    bytes

Number; the total number of bytes read from the proxied server

    responses_written

Number; the total number of responses written to the cache

    bytes_written

Number; the total number of bytes written to the cache

limit_conn#

limit_conn_zone $binary_remote_addr zone=limit_conn_zone:10m;

/status/http/limit_conns/<zone>, /status/stream/limit_conns/<zone>#

Objects for each configured limit_conn in http or limit_conn in stream contexts with the following fields

{
  "passed": 73,
  "skipped": 0,
  "rejected": 0,
  "exhausted": 0
}

passed

Number; the total number of passed connections

skipped

Number; the total number of connections passed with zero-length key, or key exceeding 255 bytes

rejected

Number; the total number of connections exceeding the configured limit

exhausted

Number; the total number of connections rejected due to exhaustion of zone storage

limit_req#

limit_req_zone $binary_remote_addr zone=limit_req_zone:10m rate=1r/s;

/status/http/limit_reqs/<zone>#

Objects for each configured limit_req with the following fields

{
  "passed": 54816,
  "skipped": 0,
  "delayed": 65,
  "rejected": 26,
  "exhausted": 0
}

passed

Number; the total number of passed connections

skipped

Number; the total number of requests passed with zero-length key, or key exceeding 65535 bytes

delayed

Number; the total number of delayed requests

rejected

Number; the total number of rejected requests

exhausted

Number; the total number of requests rejected due to exhaustion of zone storage

HTTP upstream#

New in version 1.1.0.

The zone <zone> (zone) directive specified in the upstream context enables the collection of statistics in the specified upstream zone.

upstream upstream {
        zone upstream 256k;
        server backend.example.com service=_example._tcp resolve max_conns=5;
   keepalive 4;
}

/status/http/upstreams/<upstream>#

where <upstream> is the name of any upstream specified with the zone directive

{
    "peers": {
        "192.168.16.4:80": {
            "server": "backend.example.com",
            "service": "_example._tcp",
            "backup": false,
            "weight": 5,
            "state": "up",
            "selected": {
                "current": 2,
                "total": 232
            },

            "max_conns": 5,
            "responses": {
                "200": 222,
                "302": 12
            },

            "data": {
                "sent": 543866,
                "received": 27349934
            },

            "health": {
                "fails": 0,
                "unavailable": 0,
                "downtime": 0
            },

            "sid": "<server_id>"
        }
    },

    "keepalive": 2
}

peers

Object; upstream peers statistics

    address

Object; peer’s statistics

        server

String; the parameter of the server directive

        service

String; name of service as it’s specified in server directie, if configured

        backup

Boolean; true for backup servers

        weight

Number; configured weight

        state

String; the current state of the server, can either be up, down or unavailable (when max_fails limit is reached)

        selected

Object; peer selection statistics

              current

Number; the current number of connections to peer

              total

Number; total number of requests forwarded to peer

              last

String; time in ISO 8601 format when peer was last selected

        max_conns

Number; the configured maximum number of simultaneous connections, if specified

        responses

Object; responses statistics

              <code>

Number; a non-zero number of responses with status <code> (100-599)

              xxx

Number; a non-zero number of responses with other status codes

        data

Object; data statistics

              received

Number; the total number of bytes received from peer

              sent

Number; the total number of bytes sent to peer

        health

Object; health statistics

              fails

Number; the total number of unsuccessful attempts to communicate with the peer

              unavailable

Number; how many times peer became unavailable due to reaching the max_fails limit

              downtime

Number; the total time (in milliseconds) when peer was unavailable for selection due to being unavailable

              downstart

String; time in ISO 8601 format when peer became unavailable

        sid

String; configured id of the server in upstream group

keepalive

Number; the number of currently cached connections