Implementation:Vespa engine Vespa Vespa Logctl
vespa-logctl
Tool Signature
vespa-logctl [options] <service>[:component] [<level-mods>]
Source Location
- CLI source: vespalog/src/logctl/logctl.cpp (Lines L94-230)
- ControlFile class: vespalog/src/vespa/log/control-file.cpp (Lines L1-450)
- ControlFile header: vespalog/src/vespa/log/control-file.h (Lines L1-89)
- Type: External Tool Doc
Description
vespa-logctl is a command-line tool for viewing and modifying the runtime log level settings of running Vespa processes. It operates by directly reading and writing the memory-mapped log control files that each Vespa process creates at startup. Because the control files are memory-mapped by the target processes, level changes take effect immediately without any signal or restart.
CLI Flags
| Flag | Long Form | Description |
|---|---|---|
-c |
Create the control file if it does not exist | |
-n |
Create a new entry for the specified component if it does not exist | |
-a |
Apply the operation to all control files in the control directory | |
-f <file> |
Specify an explicit control file path instead of deriving it from the service name | |
-d <dir> |
Specify the control file directory (default: $VESPA_LOG_CONTROL_DIR or /var/log/vespa/logcontrol)
| |
-r |
Reset all levels for the specified component to their default values |
Level Modification Syntax
Level modifications are specified as a comma-separated list of assignments:
<level>=<on|off>[,<level>=<on|off>]...
The special level name all applies to all 8 levels simultaneously:
| Modifier | Effect |
|---|---|
all=on |
Enable all 8 log levels (fatal, error, warning, config, info, event, debug, spam) |
all=off |
Disable all 8 log levels |
debug=on |
Enable only the debug level |
spam=off |
Disable only the spam level |
all=on,debug=off,spam=off |
Enable all levels except debug and spam (the default configuration) |
Modifiers are applied left to right, so all=on,debug=off first enables everything and then disables debug.
Usage Examples
View Current Levels
# Show all component levels for the searchnode service
vespa-logctl searchnode
Output:
searchnode.com.yahoo.search.handler ON ON ON ON ON ON OFF OFF
searchnode.com.yahoo.container ON ON ON ON ON ON OFF OFF
searchnode.com.yahoo.jdisc ON ON ON ON ON ON OFF OFF
The columns correspond to: fatal, error, warning, config, info, event, debug, spam.
Enable Debug for a Specific Component
# Enable debug logging for query handler only
vespa-logctl searchnode:com.yahoo.search.handler debug=on
Enable Debug for All Components
# Enable debug for everything in searchnode
vespa-logctl searchnode debug=on
Reset to Defaults
# Reset all components of configserver to default levels
vespa-logctl -r configserver
Use Explicit Control File
# Modify levels using a specific control file path
vespa-logctl -f /var/log/vespa/logcontrol/searchnode.logcontrol \
searchnode:com.yahoo.search debug=on
Pre-Create Component Entry
# Create a control file entry before the component has logged anything
vespa-logctl -n searchnode:com.yahoo.search.newmodule all=on
ControlFile C++ Class
The vespa-logctl tool uses the ControlFile C++ class to manipulate the memory-mapped control files.
Class Declaration
class ControlFile {
public:
enum Mode { READONLY, READWRITE, CREATE };
ControlFile(const char *filename, Mode mode);
~ControlFile();
unsigned int *getLevels(const char *name);
char *getComponentName(unsigned int offset);
void ensureComponent(const char *pattern);
void flush();
ComponentIterator begin();
ComponentIterator end();
private:
int _fd;
char *_mapBase;
size_t _mapSize;
// ...
};
Modes
| Mode | Description | Used By |
|---|---|---|
READONLY |
Open for reading only. Used when listing current levels. | vespa-logctl (no level-mods argument)
|
READWRITE |
Open for reading and writing. Used when modifying levels. | vespa-logctl (with level-mods argument)
|
CREATE |
Create the file if it does not exist. Write header and prefix. | vespa-logctl -c, Vespa processes at startup
|
Key Methods
getLevels
unsigned int *getLevels(const char *name);
Returns a pointer to the level bitmask for the named component. The pointer points directly into the memory-mapped region, so modifications are immediately visible to the target process.
ensureComponent
void ensureComponent(const char *pattern);
Ensures that an entry exists for the specified component. If no entry exists, one is created with default level settings. This is used with the -n flag to pre-register components.
flush
void flush();
Forces any pending memory-mapped writes to be synchronized to disk. Called after level modifications to ensure persistence.
ComponentIterator
The ComponentIterator allows enumeration of all registered components:
for (auto it = controlFile.begin(); it != controlFile.end(); ++it) {
printf("%s\t", it->name());
unsigned int *levels = it->levels();
for (int i = 0; i < 8; i++) {
printf("%s ", levels[i] ? "ON" : "OFF");
}
printf("\n");
}
This is the mechanism used by vespa-logctl to display the current level table when invoked without level modifications.
Internal Operation Flow
When vespa-logctl is invoked with level modifications, it performs the following steps:
- Parse arguments: Extract the service name, optional component, and level modifications from the command line.
- Locate control file: Either use the explicit
-fpath, or derive it from the service name and control directory as<dir>/<service>.logcontrol. - Open control file: Create a
ControlFileobject inREADWRITEmode (orCREATEmode with-c). - Find or create component entry: Use
getLevels()orensureComponent()to locate the entry. - Apply level modifications: Parse the level-mods string and set each level byte to 1 (on) or 0 (off).
- Flush changes: Call
flush()to ensure the changes are persisted. - Close control file: The
ControlFiledestructor unmaps and closes the file.
Interaction with Java Processes
The control file format is identical for Java and C++ processes. When vespa-logctl modifies the control file:
- Java processes see the change through their
MappedByteBuffer, which maps the same physical file. - C++ processes see the change through their
mmap()mapping of the same file.
No inter-process communication (signals, sockets, etc.) is needed. The memory-mapped file is the communication channel.
Error Handling
- If the control file does not exist and
-cis not specified, the tool prints an error and exits with a non-zero status. - If the specified component does not exist in the control file and
-nis not specified, the tool prints a warning. With the-aflag, non-matching components are silently skipped. - If the level-mods string is malformed, a usage message is printed.
Implements Principle
Related Implementations
- VespaLevelControllerRepo Constructor -- Creates the Java-side memory-mapped level controller that
vespa-logctlmodifies - VespaLogHandler.publish -- Reads the level control bytes on every log call