Kong: kong.log writes into the gateway's own log with plugin context

kong.log prefixes each line with the plugin name and request id, which is what makes a message findable. print and ngx.log lose that context.

Code
kong.log.debug("resolved tenant ", tenant)
kong.log.info("cache miss for ", key)
kong.log.warn("upstream slow: ", latency, "ms")
kong.log.err("redis unreachable: ", err)

-- structured, for a log collector
kong.log.set_serialize_value("tenant", tenant)

# kong.conf
log_level = notice     # debug | info | notice | warn | error | crit
Output
2026/08/25 09:12:44 [info] 1234#0: *5821 [kong] handler.lua:42
  [my-plugin] cache miss for tenant:acme, client: 10.0.1.4,
  request: "GET /billing HTTP/1.1"

# kong.log.debug costs nothing when log_level is above debug - the message
# is not even concatenated. Prefer several arguments over building a string
# with .. so that stays true.
#
# set_serialize_value adds a field to the JSON record the logging plugins
# emit, which is how you get a custom field into http-log.
Advertisement

Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.

Published 2026-08-25