antirez/redis — pull request #2081 by mattsta (2014-10-20 18:57:57+00:00)
Title: Proctitle noformat

This implements a dynamically updating process title based on the state of the Redis server.

The format of the new process title is:
```
{{executable}} {{name}} {{config}} {{ip0}}:{{port}} {{mode}} {{role}} {{state}}
```

where:
```haskell
executable is: argv[0]
name is: [name] |
config is : config file path |
[Note: the name and config policy is (name xor config) - If a name is set, the config path is absent.]
mode is: cluster | sentinel | (empty if regular master/replica or master-with-no-replicas setup)
role is: master | replica | (empty if standalone master with no replicas)
state is: live cluster node description | live replica description | live sentinel description | (empty if no replica _or_ if a forked background process)
```

You can see example output based on different scenarios at https://gist.github.com/mattsta/7512d430b3cc43bd669e

Creation History:
- In commit 6356cf6808be9ea88ab97be33ebf1576eeb57da6, Redis changed the way it shows up in process lists. Previously, the format was the launch command line. After commit 6356cf6808be9ea88ab97be33ebf1576eeb57da6, then format became "redis-server ip:port" — which is _largely_ not useful in many scenarios!
- personal note: When I have 10 Redis processes running on my server, I like to see them by logical name (typically the name of the config file shows is the name of the server), but having 10 servers with only port identifiers makes me consult _another_ lookup table to figure out what things are doing (or grep through pid files then match pid file contents to pid file names... it's not pretty).
- We've had people complaining about the change for a while. See https://github.com/antirez/redis/issues/694 and https://github.com/antirez/redis/issues/1979
- So, after first suggesting this [back in April](https://github.com/antirez/redis/issues/694#issuecomment-41324583), I finally got around to adding a dynamic updating proctitle interface.

Implementation History:
- I started out by allowing a user-specified format string (double curly bracket formatting). But, the format parsing code was [too ugly](https://github.com/mattsta/redis/blob/proctitle/src/redis.c#L3613-L3656), so I scrapped it in favor of [static content positions](https://github.com/mattsta/redis/blob/proctitle-noformat/src/redis.c#L3630-L3647).
- I added (or refactored out) unique state information reporters for each major mode of Redis ([master/replica](https://github.com/mattsta/redis/blob/proctitle-noformat/src/replication.c#L1333-L1345), [sentinel](https://github.com/mattsta/redis/blob/proctitle-noformat/src/sentinel.c#L2856-L2904), [cluster](https://github.com/mattsta/redis/blob/proctitle-noformat/src/cluster.c#L3560-L3607)). I tried to select the best information to show for each mode, but we can always add or remove information as necessary. (For example, I included cluster epoch in the cluster instance output, but not really sure why... it just looks neat.)
- The dynamic title updating is [triggered in serverCron()](https://github.com/mattsta/redis/blob/proctitle-noformat/src/redis.c#L1240-L1245) meaning:
- to update the process title, functions call `PROCTITLE_UPDATE()` which just sets `server.update_proctitle = 1`
- the server title update can lag server state by a second or two
- if a process updates state multiple times, the state will only be read at most once per second (this prevents Redis from flapping the title unnecessarily).
- Cluster and Sentinel both write out all state changes to config files — and it was very simple to just add the process title update flag to one place in the config writing code to trigger title updates too (since we know the state changed when the config updater is called).
- Replication state tracking is a bit more tricky; it required adding `PROCTITLE_UPDATE()` triggers in a few different places since there's no centralized "replication state updated" hook.
- Sentinel state tracking required some additional non-config-file-update-based triggers because internal per-node state (especially transitional states) aren't written out to the state/config files.
- I added a [very simple "server instance name" config option](https://github.com/mattsta/redis/commit/d9daeb778a1457867c39efd25e9d66eb894b6002) before people [started complaining about it](https://groups.google.com/forum/#!searchin/redis-db/instance$20name/redis-db/kEDe3IixFoo/moMjEOF6VFgJ). We can either keep it, remove it, or refactor it into something more extensible. I'd like to go further and have arbitrary "config metadata" per-instance, but that's out of the scope of what's needed for a simple process title name.

So, here it is.

If you've got free time and want to help double check everything here: try it out, try to make it crash, try to find any remaining edge cases where state updates don't get reflected in the title (meaning we need more `PROCTITLE_UPDATE()` calls somewhere), and try to think of any pathological conditions where the title updates could cause problems.

:shipit: