Dragonfly adds per-thread slow command logs
Dragonfly 1.12 implements SLOWLOG and announces search beta availability. Its command timer and merged per-thread buffers explain how to interpret slow-command evidence.
An aggregate command-time metric can show that a command family consumes substantial time without identifying an individual request. Dragonfly's November 3 release adds SLOWLOG support, retaining examples of commands whose measured invocation time exceeds a threshold. It also announces beta availability for search after early-adopter feedback.
The slow-log implementation has a particular relationship with Dragonfly's multithreaded architecture. Each processing thread retains its own bounded buffer. The retrieval command gathers those buffers and sorts their contents by timestamp. A client sees one response assembled from several local histories.
I find this addition useful because a larger single datastore process still needs request-level explanations for latency. Distributing execution across cores changes where evidence originates. It does not remove the need to identify which command and arguments occupied time in the server.
The measurement surrounds the handler
The release-tagged command invocation code reads a timestamp before invoking the handler and another timestamp after it returns. It converts the elapsed nanoseconds to microseconds and uses that value for command statistics and the slow-log decision.
That boundary is more precise than calling the number application latency. It measures the interval around this server-side handler invocation. It does not include the caller's entire experience before the handler begins or after the server finishes its work. Network transit and application scheduling remain outside the meaning of this particular timer.
The code reads the current thread's server state after invocation because execution may have migrated threads. That detail ties the entry to the processing context that exists when the handler returns. Capturing a thread-local pointer only before the call would ignore the possibility of migration.
Logging requires a connection, a nonzero buffer capacity, and elapsed time greater than the configured threshold. Commands marked blocking are excluded by the condition in this invocation path. A command that waits by design is therefore not necessarily represented in the log in the same way as an ordinary invocation that takes unexpectedly long.
The initial implementation patch also replaces an earlier placeholder that returned empty slow-log results. The command name existed before this release, but the patch adds retained entries and the machinery to report them. Recognizing a command and supplying its intended diagnostic information are separate compatibility stages.
Entries retain bounded argument information
The slow-log entry definition includes an entry ID, timestamp, elapsed microseconds, original argument count, and argument data. It also records the client endpoint and client name. Those fields connect the measured operation to a particular connection and request shape.
The buffer implementation caps retained argument information. Its constants limit the stored argument population and the length of an individual argument. Long argument contents are truncated, and the response indicates omitted bytes. Commands with more arguments receive a marker describing omitted arguments.
This makes the log unsuitable as a lossless request replay source. A recorded command can identify a large payload or a high-arity operation without preserving every byte needed to execute it again. The truncation rules reduce the amount of request data retained in memory.
The retained prefix still comes from application arguments. A command log consequently contains more specific information than a duration histogram. Its diagnostic value comes from those details, including the selected key and request shape where retained. That same property affects who should have access to the log.
The registration classifies SLOWLOG as an administrative command. Its ACL categories include administrative and dangerous operations. The server therefore exposes this diagnostic operation through the command-permission system rather than treating it as ordinary application data access.
Retrieval merges local histories
The server handler implements GET, LEN, and RESET, as well as help. An inspection sequence can request an explicit bounded result:
redis-cli SLOWLOG LEN
redis-cli SLOWLOG GET 10
Using an explicit count avoids depending on an omitted-count default. The retrieval path accepts minus one to request all retained entries. Values below minus one produce an error, so the numeric argument has a defined special case rather than accepting arbitrary negative limits.
For retrieval, the server copies each local circular buffer, combines the entries, and sorts them by descending timestamp. It then limits the response to the requested number. The result presents recent entries across threads, not the contents of only the thread that received the inspection command.
Returned IDs combine the local entry counter with the processing-thread index. That creates distinguishable IDs across the buffers. Timestamp sorting establishes response order, so the numeric ID should not be treated as an independent global time measurement.
The length command sums the local buffer lengths. Retention is consequently distributed across processing threads. A thread receiving many slow operations can overwrite its own older entries while another thread still retains a quieter history. A fixed local capacity does not describe a single global first-in-first-out queue.
Configuration changes the evidence retained
The implementation patch introduces a threshold of ten thousand microseconds and a maximum length setting. Configuration callbacks propagate changes to the thread-local thresholds and circular-buffer capacities. The control affects future retention as well as the memory allocated for stored entries.
A positive threshold can be changed through the registered mutable option:
redis-cli CONFIG SET slowlog_log_slower_than 5000
redis-cli SLOWLOG GET 10
This example selects a five-thousand-microsecond threshold. It does not guarantee that the following query returns any entry because the workload must actually produce an invocation meeting the logging condition.
Reset clears the local buffers across processing threads. It changes the diagnostic history rather than the application dataset. The distinction is useful when collecting a fresh observation window, since the entries retained before a workload change otherwise remain eligible for retrieval until overwritten.
I regard the merged log as a complement to aggregate metrics. A duration total can describe overall command cost, while a retained entry identifies one invocation and some of its arguments. The per-thread retention policy explains why the available examples are a bounded sample of qualifying work.
The same release's search beta adds another class of workload for that diagnostic context. The announcement marks search as beta after initial feedback. Slow-log support supplies concrete request evidence for datastore operations, with its handler timing and bounded local histories defining exactly what that evidence contains.