Package hudson.model

Class Computer

All Implemented Interfaces:
ExtensionPoint, DescriptorByNameOwner, ExecutorListener, ModelObject, SearchableModelObject, SearchItem, AccessControlled, ModelObjectWithContextMenu, HasWidgets, org.kohsuke.stapler.StaplerProxy
Direct Known Subclasses:
Jenkins.MasterComputer, SlaveComputer

@ExportedBean public abstract class Computer extends Actionable implements AccessControlled, ExecutorListener, DescriptorByNameOwner, org.kohsuke.stapler.StaplerProxy, HasWidgets
Represents the running state of a remote computer that holds Executors.

Executors on one Computer are transparently interchangeable (that is the definition of Computer).

This object is related to Node but they have some significant differences. Computer primarily works as a holder of Executors, so if a Node is configured (probably temporarily) with 0 executors, you won't have a Computer object for it (except for the built-in node, which always gets its Computer in case we have no static executors and we need to run a Queue.FlyweightTask - see JENKINS-7291 for more discussion.) Also, even if you remove a Node, it takes time for the corresponding Computer to be removed, if some builds are already in progress on that node. Or when the node configuration is changed, unaffected Computer object remains intact, while all the Node objects will go away.

This object also serves UI (unlike Node), and can be used along with TransientComputerActionFactory to add Actions to Computers.

Author:
Kohsuke Kawaguchi
  • Field Details

    • offlineCause

      protected volatile OfflineCause offlineCause
      Contains info about reason behind computer being offline.
    • nodeName

      protected String nodeName
      Node object may be created and deleted independently from this object.
    • transientActions

      protected transient List<Action> transientActions
    • statusChangeLock

      protected final Object statusChangeLock
    • threadPoolForRemoting

      public static final ExecutorService threadPoolForRemoting
    • SKIP_PERMISSION_CHECK

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public static boolean SKIP_PERMISSION_CHECK
      Escape hatch for StaplerProxy-based access control
    • PERMISSIONS

      public static final PermissionGroup PERMISSIONS
    • CONFIGURE

      public static final Permission CONFIGURE
    • EXTENDED_READ

      public static final Permission EXTENDED_READ
      Since:
      1.532
    • DELETE

      public static final Permission DELETE
    • CREATE

      public static final Permission CREATE
    • DISCONNECT

      public static final Permission DISCONNECT
    • CONNECT

      public static final Permission CONNECT
    • BUILD

      public static final Permission BUILD
    • EXTENDED_READ_AND_CONNECT

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public static final Permission[] EXTENDED_READ_AND_CONNECT
  • Constructor Details

    • Computer

      protected Computer(Node node)
  • Method Details

    • recordTermination

      public void recordTermination()
      This method captures the information of a request to terminate a computer instance. Method is public as it needs to be called from AbstractCloudSlave and Nodes. In general you should not need to call this method directly, however if implementing a custom node type or a different path for removing nodes, it may make sense to call this method in order to capture the originating request.
      Since:
      1.607
    • getTerminatedBy

      public List<Computer.TerminationRequest> getTerminatedBy()
      Returns the list of captured termination requests for this Computer. This method is used by Executor to provide details on why a Computer was removed in-between work being scheduled against the Executor and the Executor starting to execute the task.
      Returns:
      the (possibly empty) list of termination requests.
      Since:
      1.607
      See Also:
      • Executor.resetWorkUnit(String)
    • getComputerPanelBoxs

      public List<ComputerPanelBox> getComputerPanelBoxs()
      Returns list of all boxes ComputerPanelBoxs.
    • getActions

      @NonNull public List<Action> getActions()
      Returns the transient Actions associated with the computer.
      Overrides:
      getActions in class Actionable
      Returns:
      a possibly empty list
    • addAction

      public void addAction(@NonNull Action a)
      Description copied from class: Actionable
      Adds a new action. Note: calls to Actionable.getAllActions() that happen before calls to this method may not see the update. Note: this method will always modify the actions
      Overrides:
      addAction in class Actionable
    • getLogFile

      @NonNull public File getLogFile()
      This is where the log from the remote agent goes. The method also creates a log directory if required.
      See Also:
    • getLogDir

      @NonNull protected File getLogDir()
      Directory where rotated agent logs are stored. The method also creates a log directory if required.
      Since:
      1.613
    • getWorkspaceList

      public WorkspaceList getWorkspaceList()
      Gets the object that coordinates the workspace allocation on this computer.
    • getLog

      public String getLog() throws IOException
      Gets the string representation of the agent log.
      Throws:
      IOException
    • getLogText

      public AnnotatedLargeText<Computer> getLogText()
      Used to URL-bind AnnotatedLargeText.
    • getACL

      @NonNull public ACL getACL()
      Description copied from interface: AccessControlled
      Obtains the ACL associated with this object.
      Specified by:
      getACL in interface AccessControlled
      Returns:
      never null.
    • getOfflineCause

      @Exported public OfflineCause getOfflineCause()
      If the computer was offline (either temporarily or not), this method will return the cause.
      Returns:
      null if the system was put offline without given a cause.
    • getOfflineCauseReason

      @Exported public String getOfflineCauseReason()
      If the computer was offline (either temporarily or not), this method will return the cause as a string (without user info).
      Returns:
      empty string if the system was put offline without given a cause.
    • getChannel

      @Nullable public abstract hudson.remoting.VirtualChannel getChannel()
      Gets the channel that can be used to run a program on this computer.
      Returns:
      never null when isOffline()==false.
    • getDefaultCharset

      public abstract Charset getDefaultCharset()
      Gets the default charset of this computer.
      Returns:
      never null when isOffline()==false.
    • getLogRecords

      public abstract List<LogRecord> getLogRecords() throws IOException, InterruptedException
      Gets the logs recorded by this agent.
      Throws:
      IOException
      InterruptedException
    • doLaunchSlaveAgent

      public abstract void doLaunchSlaveAgent(org.kohsuke.stapler.StaplerRequest req, org.kohsuke.stapler.StaplerResponse rsp) throws IOException, javax.servlet.ServletException
      If getChannel()==null, attempts to relaunch the agent.
      Throws:
      IOException
      javax.servlet.ServletException
    • launch

      @Deprecated public final void launch()
      Deprecated.
      since 2009-01-06. Use connect(boolean)
    • connect

      public final Future<?> connect(boolean forceReconnect)
      Do the same as doLaunchSlaveAgent(StaplerRequest, StaplerResponse) but outside the context of serving a request.

      If already connected or if this computer doesn't support proactive launching, no-op. This method may return immediately while the launch operation happens asynchronously.

      Parameters:
      forceReconnect - If true and a connect activity is already in progress, it will be cancelled and the new one will be started. If false, and a connect activity is already in progress, this method will do nothing and just return the pending connection operation.
      Returns:
      A Future representing pending completion of the task. The 'completion' includes both a successful completion and a non-successful completion (such distinction typically doesn't make much sense because as soon as Computer is connected it can be disconnected by some other threads.)
      See Also:
    • _connect

      protected abstract Future<?> _connect(boolean forceReconnect)
      Allows implementing-classes to provide an implementation for the connect method.

      If already connected or if this computer doesn't support proactive launching, no-op. This method may return immediately while the launch operation happens asynchronously.

      Parameters:
      forceReconnect - If true and a connect activity is already in progress, it will be cancelled and the new one will be started. If false, and a connect activity is already in progress, this method will do nothing and just return the pending connection operation.
      Returns:
      A Future representing pending completion of the task. The 'completion' includes both a successful completion and a non-successful completion (such distinction typically doesn't make much sense because as soon as Computer is connected it can be disconnected by some other threads.)
      See Also:
    • cliConnect

      @Deprecated public void cliConnect(boolean force) throws ExecutionException, InterruptedException
      Deprecated.
      Implementation of CLI command "connect-node" moved to ConnectNodeCommand.
      Parameters:
      force - If true cancel any currently pending connect operation and retry from scratch
      Throws:
      ExecutionException
      InterruptedException
    • getConnectTime

      public final long getConnectTime()
      Gets the time (since epoch) when this computer connected.
      Returns:
      The time in ms since epoch when this computer last connected.
    • disconnect

      public Future<?> disconnect(OfflineCause cause)
      Disconnect this computer. If this is the built-in node, no-op. This method may return immediately while the launch operation happens asynchronously.
      Parameters:
      cause - Object that identifies the reason the node was disconnected.
      Returns:
      Future to track the asynchronous disconnect operation.
      Since:
      1.320
      See Also:
    • disconnect

      @Deprecated public Future<?> disconnect()
      Deprecated.
      as of 1.320. Use disconnect(OfflineCause) and specify the cause.
      Equivalent to disconnect(null)
    • cliDisconnect

      @Deprecated public void cliDisconnect(String cause) throws ExecutionException, InterruptedException
      Deprecated.
      Implementation of CLI command "disconnect-node" moved to DisconnectNodeCommand.
      Parameters:
      cause - Record the note about why you are disconnecting this node
      Throws:
      ExecutionException
      InterruptedException
    • cliOffline

      @Deprecated public void cliOffline(String cause) throws ExecutionException, InterruptedException
      Deprecated.
      Implementation of CLI command "offline-node" moved to OfflineNodeCommand.
      Parameters:
      cause - Record the note about why you are disconnecting this node
      Throws:
      ExecutionException
      InterruptedException
    • cliOnline

      @Deprecated public void cliOnline() throws ExecutionException, InterruptedException
      Deprecated.
      Implementation of CLI command "online-node" moved to OnlineNodeCommand.
      Throws:
      ExecutionException
      InterruptedException
    • getNumExecutors

      @Exported public int getNumExecutors()
      Number of Executors that are configured for this computer.

      When this value is decreased, it is temporarily possible for executors to have a larger number than this.

    • getName

      @NonNull public String getName()
    • isUnix

      @CheckForNull public abstract Boolean isUnix()
      True if this computer is a Unix machine (as opposed to Windows machine).
      Returns:
      null if the computer is disconnected and therefore we don't know whether it is Unix or not.
      Since:
      1.624
    • getNode

      @CheckForNull public Node getNode()
      Returns the Node that this computer represents.
      Returns:
      null if the configuration has changed and the node is removed, yet the corresponding Computer is not yet gone.
    • getLoadStatistics

      @Exported public LoadStatistics getLoadStatistics()
    • getTimeline

      @Deprecated @Restricted(org.kohsuke.accmod.restrictions.DoNotUse.class) public BuildTimelineWidget getTimeline()
      Deprecated.
    • isOffline

      @Exported public boolean isOffline()
    • isOnline

      public final boolean isOnline()
    • isManualLaunchAllowed

      @Exported public boolean isManualLaunchAllowed()
      This method is called to determine whether manual launching of the agent is allowed at this point in time.
      Returns:
      true if manual launching of the agent is allowed at this point in time.
    • isConnecting

      public abstract boolean isConnecting()
      Is a connect(boolean) operation in progress?
    • isJnlpAgent

      @Exported @Deprecated public boolean isJnlpAgent()
      Deprecated.
      since 2008-05-18. See isLaunchSupported() and ComputerLauncher
      Returns true if this computer is supposed to be launched via inbound protocol.
    • isLaunchSupported

      @Exported public boolean isLaunchSupported()
      Returns true if this computer can be launched by Hudson proactively and automatically.

      For example, inbound agents return false from this, because the launch process needs to be initiated from the agent side.

    • isTemporarilyOffline

      @Exported @Deprecated public boolean isTemporarilyOffline()
      Deprecated.
      You should almost always want isOffline(). This method is marked as deprecated to warn people when they accidentally call this method.
      Returns true if this node is marked temporarily offline by the user.

      In contrast, isOffline() represents the actual online/offline state. For example, this method may return false while isOffline() returns true if the agent failed to launch.

    • setTemporarilyOffline

      @Deprecated public void setTemporarilyOffline(boolean temporarilyOffline)
      Deprecated.
    • setTemporarilyOffline

      public void setTemporarilyOffline(boolean temporarilyOffline, OfflineCause cause)
      Marks the computer as temporarily offline. This retains the underlying Channel connection, but prevent builds from executing.
      Parameters:
      cause - If the first argument is true, specify the reason why the node is being put offline.
    • getIcon

      @Exported public String getIcon()
      Returns the icon for this computer. It is both the recommended and default implementation to serve different icons based on isOffline()
      See Also:
    • getIconClassName

      @Exported public String getIconClassName()
      Returns the class name that will be used to lookup the icon. This class name will be added as a class tag to the html img tags where the icon should show up followed by a size specifier given by Icon.toNormalizedIconSizeClass(String) The conversion of class tag to src tag is registered through IconSet.addIcon(Icon) It is both the recommended and default implementation to serve different icons based on isOffline()
      See Also:
    • getIconAltText

      public String getIconAltText()
    • getDisplayName

      @Exported @NonNull public String getDisplayName()
      Specified by:
      getDisplayName in interface ModelObject
    • getCaption

      public String getCaption()
    • getUrl

      public String getUrl()
    • getAssignedLabels

      @Exported public Set<LabelAtom> getAssignedLabels()
    • getTiedJobs

      public List<AbstractProject> getTiedJobs()
      Returns projects that are tied on this node.
    • getBuilds

      public RunList getBuilds()
    • setNode

      protected void setNode(Node node)
      Called to notify Computer that its corresponding Node configuration is updated.
    • kill

      protected void kill()
      Called by Jenkins.updateComputerList() to notify Computer that it will be discarded.

      Note that at this point getNode() returns null.

      See Also:
    • onRemoved

      protected void onRemoved()
      Called by Jenkins when this computer is removed.

      This happens when list of nodes are updated (for example by Jenkins.setNodes(List) and the computer becomes redundant. Such Computers get killed, then after all its executors are finished, this method is called.

      Note that at this point getNode() returns null.

      Since:
      1.510
      See Also:
    • countIdle

      public int countIdle()
      Returns the number of idle Executors that can start working immediately.
    • countBusy

      public final int countBusy()
      Returns the number of Executors that are doing some work right now.
    • countExecutors

      public final int countExecutors()
      Returns the current size of the executor pool for this computer. This number may temporarily differ from getNumExecutors() if there are busy tasks when the configured size is decreased. OneOffExecutors are not included in this count.
    • getExecutors

      @Exported @StaplerDispatchable public List<Executor> getExecutors()
      Gets the read-only snapshot view of all Executors.
    • getOneOffExecutors

      @Exported @StaplerDispatchable public List<OneOffExecutor> getOneOffExecutors()
      Gets the read-only snapshot view of all OneOffExecutors.
    • getAllExecutors

      public List<Executor> getAllExecutors()
      Gets the read-only snapshot view of all Executor instances including OneOffExecutors.
      Returns:
      the read-only snapshot view of all Executor instances including OneOffExecutors.
      Since:
      2.55
    • getDisplayExecutors

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public List<Computer.DisplayExecutor> getDisplayExecutors()
      Used to render the list of executors.
      Returns:
      a snapshot of the executor display information
      Since:
      1.607
    • isIdle

      @Exported public final boolean isIdle()
      Returns true if all the executors of this computer are idle.
    • isPartiallyIdle

      public final boolean isPartiallyIdle()
      Returns true if this computer has some idle executors that can take more workload.
    • getIdleStartMilliseconds

      public final long getIdleStartMilliseconds()
      Returns the time when this computer last became idle.

      If this computer is already idle, the return value will point to the time in the past since when this computer has been idle.

      If this computer is busy, the return value will point to the time in the future where this computer will be expected to become free.

    • getDemandStartMilliseconds

      public final long getDemandStartMilliseconds()
      Returns the time when this computer first became in demand.
    • getDescription

      @Restricted(org.kohsuke.accmod.restrictions.DoNotUse.class) @Exported @NonNull public String getDescription()
      Returns the Node description for this computer. Empty String if the Node is null.
    • removeExecutor

      protected void removeExecutor(Executor e)
      Called by Executor to kill excessive executors from this computer.
    • isAlive

      protected boolean isAlive()
      Returns true if any of the executors are active.
      Since:
      1.509
    • interrupt

      public void interrupt()
      Interrupt all Executors. Called from Jenkins.cleanUp().
    • getSearchUrl

      public String getSearchUrl()
      Description copied from interface: SearchItem
      Returns the URL of this item relative to the parent SearchItem.
      Specified by:
      getSearchUrl in interface SearchItem
      Returns:
      URL like "foo" or "foo/bar". The path can end with '/'. The path that starts with '/' will be interpreted as the absolute path (within the context path of Jenkins.)
    • getRetentionStrategy

      public abstract RetentionStrategy getRetentionStrategy()
      RetentionStrategy associated with this computer.
      Returns:
      never null. This method return RetentionStrategy<? super T> where T=this.getClass().
    • getMonitorData

      @Exported(inline=true) public Map<String,Object> getMonitorData()
      Expose monitoring data for the remote API.
    • getMonitoringData

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public Map<NodeMonitor,Object> getMonitoringData()
    • getSystemProperties

      public Map<Object,Object> getSystemProperties() throws IOException, InterruptedException
      Gets the system properties of the JVM on this computer. If this is the master, it returns the system property of the master computer.
      Throws:
      IOException
      InterruptedException
    • getEnvVars

      Deprecated.
      as of 1.292 Use getEnvironment() instead.
      Throws:
      IOException
      InterruptedException
    • getEnvironment

      public EnvVars getEnvironment() throws IOException, InterruptedException
      Returns cached environment variables (copy to prevent modification) for the JVM on this computer. If this is the master, it returns the system property of the master computer.
      Throws:
      IOException
      InterruptedException
    • buildEnvironment

      @NonNull public EnvVars buildEnvironment(@NonNull TaskListener listener) throws IOException, InterruptedException
      Creates an environment variable override to be used for launching processes on this node.
      Throws:
      IOException
      InterruptedException
      Since:
      1.489
      See Also:
    • getThreadDump

      public Map<String,String> getThreadDump() throws IOException, InterruptedException
      Gets the thread dump of the agent JVM.
      Returns:
      key is the thread name, and the value is the pre-formatted dump.
      Throws:
      IOException
      InterruptedException
    • getHeapDump

      public RemotingDiagnostics.HeapDump getHeapDump() throws IOException
      Obtains the heap dump.
      Throws:
      IOException
    • getHostName

      public String getHostName() throws IOException, InterruptedException
      This method tries to compute the name of the host that's reachable by all the other nodes.

      Since it's possible that the agent is not reachable from the master (it may be behind a firewall, connecting to master via inbound protocol), this method may return null. It's surprisingly tricky for a machine to know a name that other systems can get to, especially between things like DNS search suffix, the hosts file, and YP.

      So the technique here is to compute possible interfaces and names on the agent, then try to ping them from the master, and pick the one that worked.

      The computation may take some time, so it employs caching to make the successive lookups faster.

      Returns:
      null if the host name cannot be computed (for example because this computer is offline, because the agent is behind the firewall, etc.)
      Throws:
      IOException
      InterruptedException
      Since:
      1.300
    • doRssAll

      @Restricted(org.kohsuke.accmod.restrictions.DoNotUse.class) public void doRssAll(org.kohsuke.stapler.StaplerRequest req, org.kohsuke.stapler.StaplerResponse rsp) throws IOException, javax.servlet.ServletException
      Throws:
      IOException
      javax.servlet.ServletException
    • doRssFailed

      @Restricted(org.kohsuke.accmod.restrictions.DoNotUse.class) public void doRssFailed(org.kohsuke.stapler.StaplerRequest req, org.kohsuke.stapler.StaplerResponse rsp) throws IOException, javax.servlet.ServletException
      Throws:
      IOException
      javax.servlet.ServletException
    • doRssLatest

      @Restricted(org.kohsuke.accmod.restrictions.DoNotUse.class) public void doRssLatest(org.kohsuke.stapler.StaplerRequest req, org.kohsuke.stapler.StaplerResponse rsp) throws IOException, javax.servlet.ServletException
      Retrieve the RSS feed for the last build for each project executed in this computer. Only the information from AbstractProject is displayed since there isn't a proper API to gather information about the node where the builds are executed for other sorts of projects such as Pipeline
      Throws:
      IOException
      javax.servlet.ServletException
      Since:
      2.215
    • doToggleOffline

      public org.kohsuke.stapler.HttpResponse doToggleOffline(@QueryParameter String offlineMessage) throws IOException, javax.servlet.ServletException
      Throws:
      IOException
      javax.servlet.ServletException
    • doChangeOfflineCause

      public org.kohsuke.stapler.HttpResponse doChangeOfflineCause(@QueryParameter String offlineMessage) throws IOException, javax.servlet.ServletException
      Throws:
      IOException
      javax.servlet.ServletException
    • getApi

      public Api getApi()
    • doDumpExportTable

      public void doDumpExportTable(org.kohsuke.stapler.StaplerRequest req, org.kohsuke.stapler.StaplerResponse rsp) throws IOException, javax.servlet.ServletException, InterruptedException
      Dumps the contents of the export table.
      Throws:
      IOException
      javax.servlet.ServletException
      InterruptedException
    • doScript

      public void doScript(org.kohsuke.stapler.StaplerRequest req, org.kohsuke.stapler.StaplerResponse rsp) throws IOException, javax.servlet.ServletException
      For system diagnostics. Run arbitrary Groovy script.
      Throws:
      IOException
      javax.servlet.ServletException
    • doScriptText

      public void doScriptText(org.kohsuke.stapler.StaplerRequest req, org.kohsuke.stapler.StaplerResponse rsp) throws IOException, javax.servlet.ServletException
      Run arbitrary Groovy script and return result as plain text.
      Throws:
      IOException
      javax.servlet.ServletException
    • _doScript

      protected void _doScript(org.kohsuke.stapler.StaplerRequest req, org.kohsuke.stapler.StaplerResponse rsp, String view) throws IOException, javax.servlet.ServletException
      Throws:
      IOException
      javax.servlet.ServletException
    • doConfigSubmit

      @POST public void doConfigSubmit(org.kohsuke.stapler.StaplerRequest req, org.kohsuke.stapler.StaplerResponse rsp) throws IOException, javax.servlet.ServletException, Descriptor.FormException
      Accepts the update to the node configuration.
      Throws:
      IOException
      javax.servlet.ServletException
      Descriptor.FormException
    • doConfigDotXml

      @WebMethod(name="config.xml") public void doConfigDotXml(org.kohsuke.stapler.StaplerRequest req, org.kohsuke.stapler.StaplerResponse rsp) throws IOException, javax.servlet.ServletException
      Accepts config.xml submission, as well as serve it.
      Throws:
      IOException
      javax.servlet.ServletException
    • updateByXml

      public void updateByXml(InputStream source) throws IOException, javax.servlet.ServletException
      Updates Job by its XML definition.
      Throws:
      IOException
      javax.servlet.ServletException
      Since:
      1.526
    • doDoDelete

      public org.kohsuke.stapler.HttpResponse doDoDelete() throws IOException
      Really deletes the agent.
      Throws:
      IOException
    • waitUntilOnline

      public void waitUntilOnline() throws InterruptedException
      Blocks until the node becomes online/offline.
      Throws:
      InterruptedException
    • waitUntilOffline

      public void waitUntilOffline() throws InterruptedException
      Throws:
      InterruptedException
    • doProgressiveLog

      public void doProgressiveLog(org.kohsuke.stapler.StaplerRequest req, org.kohsuke.stapler.StaplerResponse rsp) throws IOException
      Handles incremental log.
      Throws:
      IOException
    • getTarget

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public Object getTarget()
      Specified by:
      getTarget in interface org.kohsuke.stapler.StaplerProxy
    • currentComputer

      @Nullable public static Computer currentComputer()
      Gets the current Computer that the build is running. This method only works when called during a build, such as by Publisher, BuildWrapper, etc.
      Returns:
      the Computer associated with Executor.currentExecutor(), or (consistently as of 1.591) null if not on an executor thread
    • isAcceptingTasks

      @OverrideMustInvoke public boolean isAcceptingTasks()
      Returns true if the computer is accepting tasks. Needed to allow agents programmatic suspension of task scheduling that does not overlap with being offline.
      Returns:
      true if the computer is accepting tasks
      See Also:
    • resolveForCLI

      @CLIResolver public static Computer resolveForCLI(String name) throws org.kohsuke.args4j.CmdLineException
      Used for CLI binding.
      Throws:
      org.kohsuke.args4j.CmdLineException
    • relocateOldLogs

      @Initializer public static void relocateOldLogs()
      Relocate log files in the old location to the new location. Files were used to be $JENKINS_ROOT/slave-NAME.log (and .1, .2, ...) but now they are at $JENKINS_ROOT/logs/slaves/NAME/slave.log (and .1, .2, ...)
      See Also: