Table of Contents
Watcher is a mechanism that exposes internal operational parameters of a running BigWorld Server so that a developer or administrator can view and change these parameters.
All BigWorld components use the Watcher interface. You can easily extend your own processes to use this interface. To enable this, the targeted server component code needs to be modified-one needs to first register a watcher interface instance, and then specify the internal parameters to be exposed through watchers.
There are a number of watcher types, such as DataWatcher, DirectoryWatcher, and FunctionWatcher, among others. You can build a tree of different type of watchers logically linked together. To do this, you need to first create a new DirectoryWatcher, and then add to the tree using the function addChild() of the parent watcher. The root of the watcher tree can be obtained by calling the static function Watcher::rootWatcher().
In the case where watchers are attached to the root only, the macro MF_WATCH is provided to simplify the process. For more details on adding new watchers, check the existing examples in the server source code and the C++ API documentation.
Once watchers are enabled, the running server process grants access to its internal statistics and debug information.
Background Watcher processes can collect watcher data and republish it through WebConsole's ClusterControl module. WebConsole's StatGrapher module can poll and graph watcher data. For details on WebConsole, see the document Server Operations Guide's section Cluster Administration Tools → WebConsole.
Both Python and C++ functions can be exposed as BigWorld Watchers which enables them to be 'called' via the watcher protocol.
When a function watcher has been invoked, three pieces of data will be returned to the invoker:
-
Call success status
This is a boolean True / False representing whether or not the callable watcher successfully completed running.
A situation that may generate a status of False would be a Python function that throws an exception that is not caught. Such status should be rare, and we suggest that it should only happen during development of the callable functions.
-
Function return data
This is recommended to be a human-readable string, indicating the resulting state/information pertaining to the operation of the called watcher.
For example, a callable watcher that changes the position of a specific entity number may return 'Entity
<id>
moved to (x,y,z).' on success, or 'No entity with id<id>
found.' if the entity did not exist at the time of calling the watcher. -
Console output (stdout/stderr)
This is intended to provide a mechanism for developers writing callable watchers to catch error states and have access to debugging information while development is occurring.
Any exception thrown in Python scripts will be be in this segment of the return data. Console output may however also be useful for providing more detailed information about a callable watcher operation.
For example, a callable watcher may be defined to display all entities of type PlayerAvatar. The Function Return Data piece of data may output 'Found
<count>
entities of type PlayerAvatar', while the console output may display summary information for each of the entities.
Callable function watchers can be defined in two ways:
-
Via Python code, such as the ones in your game's base or cell entities' resource directories.
For details on how to implement Python function watchers, see Implementing Function Watchers.
-
Via C++ in server components.
Currently, C++ support for callable watchers is limited ‐ if you wish to use C++ callable watchers, then please contact BigWorld support for further information on how to use and implement these watchers.
Note
In order to enable any callable function watchers to be exposed on the WebConsole's Commands → My Commands page, it is necessary to place the watcher under the command watcher path.
The concept of watcher forwarding was introduced because quite often the knowledge of how best to run a callable function watcher is not known by the person using it ‐ i.e., decisions such as if should all CellApps run the watcher to generate a comprehensive report, or should it be run on the first available CellApp to perform an action.
Watcher forwarding allows a component manager (e.g., CellAppMgr, BaseAppMgr) to forward a callable watcher request to any of its owned components, thus allowing the developer of the callable watcher to determine how best to expose the watchers functionality for general use.
The decision regarding how best to run a callable watcher is encoded by the developer via an exposure hint. Currently there are 2 forms of expose hints:
-
Least Loaded:
Run the callable watcher on the component with the least load of all known components owned by the manager.
-
All
Run the callable watcher on all components owned by the manager.
Python function watchers can be added either via a component PyConsole for development purposes, or via game script for a persistent callable watcher. Adding a watcher requires using the BigWorld.addFunctionWatcher method (for details, see BaseApp Python API, CellApp Python API, or Client Python API).
Generally function watchers are added to pre-existing Python functions which functionality would be useful to expose to a wider audience. Below is a brief example of a function being exposed via a watcher.
def addGuardReturnMessage( num ):count = 0 resultStr = "" try: count = util.addGuards( num ) resultStr = "Added %s guards." % count except Exception, e: print e resultStr = "Unable to add %s guards." % num return resultStr BigWorld.addFunctionWatcher( "command/addGuards",
addGuardReturnMessage,
[("Number of guards to add", int)],
BigWorld.EXPOSE_LEAST_LOADED,
"Add an arbitrary number of patrolling guards into the world.")
addGuardReturnMessage acts as a wrapper function for util.addGuards, to provide more meaningful output for WebConsole display. |
|
command/addGuards is the watcher path the function watcher will be exposed at. |
|
addGuardReturnMessage is the function name the watcher should call when a request is received at the watcher path. |
|
The argument list is defined as a list of tuples, with each tuple containing argument name and the type of the value to be expected. |
|
BigWorld.EXPOSE_LEAST_LOADED indicates to the component manager to run the watcher request on the component with the lowest load. |
|
This is a longer description of the function watcher, which can be useful in outlining any peculiarities or caveats with the function watcher. |
More examples can be found in
fantasydemo/res/scripts/base/Watchers.py
and
fantasydemo/res/scripts/cell/Watchers.py
.