LOGGING.YAML(5)

πŸ“¦
version 9.2.5 Β· 5 versions
, in ubuntu questing

✨ LOGGING.YAML(5) ✨

okay bestie, so this is the manual page for logging.yaml from the Apache Traffic Server fam (section 5 of the manual, iykyk). it's the file that defines all your custom log file formats, filters, and processing options. buckle up πŸ’…


πŸ’– NAME πŸ’–

logging.yaml β€” this file defines all custom log file formats, filters, and processing options. that's the whole vibe. 🌸

IMPORTANT, fr fr: this config file replaces the XML-based logs_xml.config, AND the Lua-based logging.config from past Traffic Server releases. so if you're upgrading from a Traffic Server release that used either the XML or the Lua config format, and you made custom log formats, filters, and destinations? yeah you gotta update all of those settings to this format. no cap. 😭

πŸ¦‹ LOG DEFINITIONS πŸ¦‹

so custom logs get configured by the combo of three key elements: a format, an optional filter, and a log destination. it's giving trinity. πŸ‘‘

  • a format defines how log lines will appear (and also whether the logs using that format are gonna be event logs or summary logs).
  • a filter defines what events do, and what events don't, make it into the logs that use the filter.
  • a log defines where the record of events or summaries actually ends up.

🌸 Formats 🌸

custom logging formats can be handed directly to a log definition, or they can be defined as a reusable variable in your logging.yaml for easy reference β€” especially when you've got more than one log using the same format. which approach you pick is literally entirely up to you, but it's strongly recommended to make an explicit format object if you're gonna reuse the same format across multiple log files. bestie behavior. πŸ’–

custom formats are defined by picking a name to identify the format, plus a format string that defines the output format string for every event. there's also an optional interval attribute you can specify to define the aggregation interval for summary logs. ✨

# A one-line-per-event format that just prints event timestamps.
formats:
- name: myformat
  format: '%<cqtq>'

# An aggregation/summary format that prints the last event timestamp from
# the interval along with the total count of events in the same interval.
# (Doing so every 30 seconds.)
formats:
- name: mysummaryformat
  format: '%<LAST(cqtq)> %<COUNT(*)>'
  interval: 30

you may define as many and as varied a collection of format objects as you desire. go off, honestly. 🌈


πŸŽ€ Format Specification πŸŽ€

the format specification you provide as the required format attribute of the objects listed in formats is a simple string β€” whatever mixture of logging field variables and literal characters meets your needs. logging fields get discussed in great detail in the Log Fields section.

flexible enough to not only emulate the logging formats of most other proxy and HTTP servers, but to also provide even finer detail than many of them β€” the logging fields are very easy to use. within the format string, logging fields are indicated by enclosing their name within angle brackets (< and >), preceded by a percent symbol (%). for example, going back to that altogether-too-simple format from earlier, this format string:

'%<cqtq>'

defines a format where nothing but the value of the logging field cqtq is interpolated for each event's entry in the log. but we could include some literal characters in the log output by updating the format spec like so:

'Event received at %<cqtq>'

because the string "Event received at " (trailing space included, don't forget her πŸ’…) is just a bunch of characters, not enclosed in %<...>, it gets repeated verbatim in the logging output.

multiple logging fields may of course be used:

'%<cqtq> %<chi> %<cqhm> %<cqtx>'

each logging field is separately enclosed in its own percent-brace set. one set per field, no sharing. πŸ™ˆ

now, there are a small number of logging fields that extend this simple format β€” primarily the ones dealing with request and response headers. instead of defining a separate logging field name for every single possible HTTP header (an impossible task, given that arbitrary vendor/application headers may be present in both requests and responses), there are instead single logging fields for each of the major stages of an event lifecycle that permit access to named headers, like:

'%<{User-Agent}cqh>'

which emits to the log the value of the client request's User-Agent HTTP header. other stages of the event lifecycle have similar logging fields: pqh (proxy requests), ssh (origin server responses), and psh (proxy responses). iconic, honestly. πŸ‘‘

you'll find a complete listing of the available fields in Log Fields.


⭐ Aggregation Interval ⭐

every format may be given an optional interval value, specified as the number of seconds over which events destined for a log using the format are aggregated and summarized. logs that use formats containing an aggregation interval do not behave like regular logs with a single line for every event. instead, they emit a single line only every interval-seconds. slay but make it periodic. πŸ•

these types of logs are described in more detail in Summary Logs.

formats have no interval by default, and will generate event-based logs unless given one.


πŸ’œ Filters πŸ’œ

Trafficserver supports different types of filters: accept, reject and wipe_field_value. they may be used, optionally, to accept, reject logging or mask query param values for matching events. ✨

filter objects are created by assigning them a name to be used later to refer to the filter, plus an action (either accept, reject or wipe_field_value). accept, reject or wipe_field_value filters require a condition against which to match all events. the condition fields must be in the following format:

<field> <operator> <value>

for example, this snippet defines a filter that matches all POST requests:

filters:
- name: postfilter
  action: accept
  condition: cqhm MATCH POST

🌸 Filter Fields 🌸

the log fields have already been discussed in the Formats section above. for a reference to the available log field names, see Log Fields. unlike with the log format specification, you do not wrap the log field names in any additional markup. just the name, bestie. 🫢


πŸ¦‹ Filter Operators πŸ¦‹

the operators describe how to perform the matching in the filter rule, and may be any one of the following:

  • MATCH β€” true if the values of field and value are identical. case-sensitive.
  • CASE_INSENSITIVE_MATCH β€” true if the values of field and value are identical. case-insensitive.
  • CONTAIN β€” true if the value of field contains value (i.e. value is a substring of the contents of field). case-sensitive.
  • CASE_INSENSITIVE_CONTAIN β€” true if the value of field contains value (i.e. value is a substring of the contents of field). case-insensitive.

πŸŽ€ Filter Values πŸŽ€

the final component of a filter string specifies the value against which the name field will be compared.

for integer matches, all of the operators are effectively equivalent and require the field to be equal to the given integer. if you wish to match multiple integers, provide a comma separated list like this:

<field> <operator> 4,5,6,7

string matches work similarly to integer matches. multiple matches are also supported via a comma separated list. for example:

<field> <operator> e1host,host2,hostz

for IP addresses, ranges may be specified by separating the first address and the last of the range with a single - dash, as 10.0.0.0-10.255.255.255 which gives the ranges for the 10/8 network. other network notations are not supported at this time. don't try it. 😭

NOTE: it may be tempting to attach multiple Filters to a log object to reject multiple log fields (in lieu of providing a single comma separated list to a single Filter). avoid this temptation and use a comma separated list of reject objects instead. remember that you may not have multiple accept filter objects. attaching multiple filters does the opposite of what you'd expect. if, for example, we had 2 accept log filters, each disjoint from the other, nothing will ever get logged on the given log object. it's giving self-sabotage. πŸ’€

🌈 Logs 🌈

up to this point, we've only described what events should be logged and what they should look like in the logging output. now we define where those logs should be sent. ✨

three options currently exist for the type of logging output: ascii, binary, and ascii_pipe. which type you choose depends largely on how you intend to process the logs with other tools, and a discussion of the merits of each is covered elsewhere, in Deciding Between ASCII or Binary Output. 🫢


okay bestie, these are the attributes you're gonna drop into your logging object. only filename and format are required β€” everything else is a lil bonus πŸ’…

  • filename (string) β€” the name of the logfile, relative to the default logging directory (the one you set with proxy.config.log.logfile_dir). if you set this to stdout or stderr, then the stdout or stderr stream gets logged to, respectively. iconic behavior honestly.
  • format (string) β€” a string with a valid named format specification.
  • header (string) β€” if present, it gets emitted as the first line of each new log file. cute lil signature.
  • rolling_enabled (see below πŸ‘€) β€” determines the type of log rolling to use (or whether to disable rolling entirely). Overrides proxy.config.log.rolling_enabled.
  • rolling_interval_sec (number) β€” interval in seconds between log file rolling. Overrides proxy.config.log.rolling_interval_sec.
  • rolling_offset_hr (number) β€” specifies an hour (from 0 to 23) at which log rolling is guaranteed to align. Only has an effect if RollingIntervalSec is set to greater than one hour. Overrides proxy.config.log.rolling_offset_hr.
  • rolling_size_mb (number) β€” size, in megabytes, at which log files are rolled.
  • rolling_min_count (number) β€” specifies the minimum number of rolled logs to keep.
  • filters (array of filters) β€” the optional list of filter objects which restrict the individual events logged. heads up: the array may only contain one accept filter. one. singular. periodt.

so like, enabling log rolling can happen globally in records.config, or on a per-log basis by passing the right values for the rolling_enabled key. the per-log route is also how you get different rolling settings for individual logs β€” main character customization energy fr fr. the numeric values you can pass are the same ones proxy.config.log.rolling_enabled uses. and for convenience and readability, these predefined variables can also be used in logging.yaml:

  • log.roll.none β€” disable log rolling.
  • log.roll.time β€” roll at a certain time frequency, specified by RollingIntervalSec and RollingOffsetHr.
  • log.roll.size β€” roll when the size exceeds RollingSizeMb.
  • log.roll.both β€” roll when either the specified rolling time is reached or the specified file size is reached.
  • log.roll.any β€” roll the log file when the specified rolling time is reached if the size of the file equals or exceeds the specified size.

🌈 EXAMPLES 🌈

here's a format that collects info using three common fields:

formats:
- name: minimalfmt
  format: '%<chi> , %<cqu> , %<pssc>'

and here's a format that uses aggregate operators to produce a summary log, because we love a lil recap ✨

formats:
- name: summaryfmt
  format: '%<LAST(cqts)>:%<COUNT(*)>:%<SUM(psql)>'
  interval: 10

this next one is a filter that causes only REFRESH_HIT events to be logged. exclusive much?

filters:
- name: refreshhitfilter
  action: accept
  condition: pssc MATCH REFRESH_HIT

now a log specification that creates a local log file for the minimal format we defined earlier. the log filename will be minimal.log because we select the ASCII logging format. iykyk πŸŽ€

logs:
- mode: ascii
  filename: minimal
  format: minimalfmt

and finally, a log specification that creates a local log file using the summary format from earlier, and only includes events that matched the REFRESH_HIT filter we made. obsessed.

logs:
- mode: ascii
  filename: refreshhit_summary
  format: summaryfmt
  filters:
  - refreshhitfilter

2026, dev@trafficserver.apache.org


and that's a wrap on this whole page, bestie 🫢 this was Apache Traffic Server 9.2, dated Feb 12, 2026 β€” go forth and roll them logs like the icon you are. mwah πŸ’…βœ¨

πŸ“¦ where this page comes from