Add a default logging parameter to daemon command invocations to make diagnosing problems easier, add a troubleshooting section to the README.md that explains how to investigate logs
This commit is contained in:
parent
dad1f2f7ca
commit
5bf40eb7d5
52
README.md
52
README.md
|
@ -75,7 +75,13 @@ $ nix-env -f default.nix -iA sysvinit
|
|||
```
|
||||
|
||||
To work with a different process manager, you should replace `sysvinit` with
|
||||
any of the supported process managers listed above.
|
||||
any of the supported process managers listed in the previous section. For
|
||||
example, to use utilities to generate and deploy `systemd` configurations, you
|
||||
should run:
|
||||
|
||||
```bash
|
||||
$ nix-env -f default.nix -iA systemd
|
||||
```
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
@ -653,6 +659,50 @@ This repository contains three example systems, that can be found in the
|
|||
files so that these system services can be deployed as Disnix containers --
|
||||
services in which other services can be hosted.
|
||||
|
||||
Troubleshooting
|
||||
===============
|
||||
This section contains a number of known problems and their resolutions.
|
||||
|
||||
Inspecting log files
|
||||
--------------------
|
||||
When a service does not work as expected, then it is typically desired to check
|
||||
the logs of the corresponding service. Although many process management concepts
|
||||
are standardized by this framework, logging is not standardized at all.
|
||||
|
||||
This section contains some pointers for some of the process management solution
|
||||
targets that are currently implemented.
|
||||
|
||||
### systemd and docker
|
||||
|
||||
Some process/service managers have their own logging facility. For example,
|
||||
`systemd` provides `journalctl`, and `docker` provides `docker logs`. They
|
||||
automatically capture the output (the `stdout` and `stderr`) of foreground
|
||||
processes.
|
||||
|
||||
### sysvinit, bsdrc, disnix
|
||||
|
||||
For process management solutions that rely on processes that deamonize on their
|
||||
own (`sysvinit`, `bsdrc` and `disnix`), you need to consult the logs that are
|
||||
managed by the services themselves (a daemon typically detaches itself from the
|
||||
`stdout` and `stderr`. As a result, a process manager cannot do it).
|
||||
|
||||
Services that only provide foreground processes are automatically daemonized
|
||||
with the `daemon` command by these three backends. By default, the `daemon`
|
||||
command will capture their outputs in log files with a `nixproc-` prefix in
|
||||
the log directory. On a production system, such a log file could be:
|
||||
`/var/log/nixproc-myservice.log`.
|
||||
|
||||
### supervisord
|
||||
|
||||
`supervisord` will (if no settings have been configured) store log files
|
||||
(capturing the `stdout` and `stderr` of each process) in the temp directory
|
||||
(typically `/tmp` or the value of the `TMPDIR` environment variable).
|
||||
|
||||
### cygrunsrv
|
||||
|
||||
By default, the `stderr` of `cygrunsrv` managed services are captured in the log
|
||||
folder. An example could be: `/var/log/myservice.log`.
|
||||
|
||||
License
|
||||
=======
|
||||
The contents of this package is available under the same license as Nixpkgs --
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
let
|
||||
createManagedProcess = import ../../nixproc/create-managed-process/agnostic/create-managed-process-universal.nix {
|
||||
inherit pkgs runtimeDir stateDir tmpDir forceDisableUserChange processManager;
|
||||
inherit pkgs runtimeDir stateDir logDir tmpDir forceDisableUserChange processManager;
|
||||
};
|
||||
in
|
||||
{
|
||||
|
|
|
@ -32,7 +32,7 @@ rec {
|
|||
};
|
||||
};
|
||||
|
||||
postgresql = rec {
|
||||
/*postgresql = rec {
|
||||
port = 6432;
|
||||
|
||||
pkg = constructors.postgresql {
|
||||
|
@ -69,5 +69,5 @@ rec {
|
|||
|
||||
docker = {
|
||||
pkg = constructors.docker;
|
||||
};
|
||||
};*/
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
let
|
||||
createManagedProcess = import ../../nixproc/create-managed-process/agnostic/create-managed-process-universal.nix {
|
||||
inherit pkgs runtimeDir stateDir tmpDir forceDisableUserChange processManager;
|
||||
inherit pkgs runtimeDir stateDir logDir tmpDir forceDisableUserChange processManager;
|
||||
};
|
||||
|
||||
webappExpr = if webappMode == "foreground" then ./webapp-fg.nix
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
let
|
||||
createSystemVInitScript = import ../../nixproc/create-managed-process/sysvinit/create-sysvinit-script.nix {
|
||||
inherit (pkgs) stdenv writeTextFile daemon;
|
||||
inherit runtimeDir tmpDir forceDisableUserChange;
|
||||
inherit runtimeDir logDir tmpDir forceDisableUserChange;
|
||||
|
||||
createCredentials = import ../../nixproc/create-credentials {
|
||||
inherit (pkgs) stdenv;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
, pkgs ? import <nixpkgs> { inherit system; }
|
||||
, stateDir ? "/var"
|
||||
, runtimeDir ? "${stateDir}/run"
|
||||
, logDir ? "${stateDir}/log"
|
||||
, tmpDir ? (if stateDir == "/var" then "/tmp" else "${stateDir}/tmp")
|
||||
, forceDisableUserChange ? false
|
||||
}:
|
||||
|
@ -12,7 +13,7 @@ let
|
|||
createManagedProcessFromConfig = configFile:
|
||||
let
|
||||
createManagedProcess = import ./create-managed-process-universal.nix {
|
||||
inherit pkgs stateDir runtimeDir tmpDir forceDisableUserChange processManager;
|
||||
inherit pkgs stateDir runtimeDir logDir tmpDir forceDisableUserChange processManager;
|
||||
};
|
||||
|
||||
properties = builtins.fromJSON (builtins.readFile configFile);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{pkgs, runtimeDir, tmpDir, stateDir, forceDisableUserChange ? false, processManager ? null}:
|
||||
{pkgs, runtimeDir, logDir, tmpDir, stateDir, forceDisableUserChange ? false, processManager ? null}:
|
||||
|
||||
let
|
||||
basePackages = [
|
||||
|
@ -14,7 +14,7 @@ let
|
|||
|
||||
createSystemVInitScript = import ../sysvinit/create-sysvinit-script.nix {
|
||||
inherit (pkgs) stdenv writeTextFile daemon;
|
||||
inherit createCredentials runtimeDir tmpDir forceDisableUserChange;
|
||||
inherit createCredentials runtimeDir logDir tmpDir forceDisableUserChange;
|
||||
|
||||
initFunctions = import ../sysvinit/init-functions.nix {
|
||||
inherit (pkgs) stdenv fetchurl;
|
||||
|
@ -90,7 +90,7 @@ let
|
|||
|
||||
generateProcessScript = import ../agnostic/generate-process-script.nix {
|
||||
inherit (pkgs) stdenv writeTextFile daemon;
|
||||
inherit createProcessScript runtimeDir tmpDir forceDisableUserChange basePackages;
|
||||
inherit createProcessScript runtimeDir logDir tmpDir forceDisableUserChange basePackages;
|
||||
};
|
||||
|
||||
createDockerContainer = import ../docker/create-docker-container.nix {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{ createProcessScript, writeTextFile, stdenv, daemon, basePackages
|
||||
, runtimeDir, tmpDir, forceDisableUserChange
|
||||
, runtimeDir, logDir, tmpDir, forceDisableUserChange
|
||||
}:
|
||||
|
||||
let
|
||||
|
@ -62,6 +62,10 @@ let
|
|||
args = foregroundProcessArgs;
|
||||
pidFile = _pidFile;
|
||||
user = _user;
|
||||
outputLogFile = util.autoGenerateDaemonLogFilePath {
|
||||
inherit name instanceName logDir;
|
||||
enableDaemonOutputLogging = true;
|
||||
};
|
||||
inherit pidFilesDir;
|
||||
}
|
||||
else throw "I don't know how to start this process!";
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
, defaultStopSignal ? "TERM"
|
||||
# Default run time directory where PID files are stored
|
||||
, runtimeDir ? "/var/run"
|
||||
# Directory in which log files are stored
|
||||
, logDir ? "/var/log"
|
||||
# Directory in which temp files are stored
|
||||
, tmpDir ? "/tmp"
|
||||
# Specifies whether user changing functionality should be disabled or not
|
||||
|
@ -31,6 +33,8 @@ name
|
|||
, commandArgs ? []
|
||||
# Specifies whether the command daemonizes or not. If the command is not a daemon, it gets daemonized by the generator
|
||||
, commandIsDaemon ? true
|
||||
# Whether to disable logging the daemon process' output
|
||||
, enableDaemonOutputLogging ? true
|
||||
# Specifies the signal that needs to be sent to reload a process
|
||||
, reloadSignal ? "HUP"
|
||||
# Specifies the signal that needs to be sent to stop a process
|
||||
|
@ -92,9 +96,14 @@ let
|
|||
inherit user forceDisableUserChange;
|
||||
};
|
||||
|
||||
outputLogFile = util.autoGenerateDaemonLogFilePath {
|
||||
inherit name instanceName logDir enableDaemonOutputLogging;
|
||||
};
|
||||
|
||||
_command = if commandIsDaemon then command else "daemon";
|
||||
_commandArgs = if commandIsDaemon then commandArgs else
|
||||
stdenv.lib.optionals (pidFile != null) [ "-p" pidFile ]
|
||||
++ stdenv.lib.optionals (outputLogFile != null) [ "-o" outputLogFile ]
|
||||
++ [ command ]
|
||||
++ commandArgs;
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
, statusCommand ? "statusproc"
|
||||
# Default run time directory where PID files are stored
|
||||
, runtimeDir ? "/var/run"
|
||||
# Directory in which log files are stored
|
||||
, logDir ? "/var/log"
|
||||
# Directory in which temp files are stored
|
||||
, tmpDir ? "/tmp"
|
||||
# Specifies the implementation of the restart activity that is used for all sysvinit scripts. Typically, there is little reason to change it.
|
||||
|
@ -63,6 +65,8 @@ name
|
|||
, process ? null
|
||||
# Specifies that the process is a daemon. If a process is not a daemon, then the generator will automatically daemonize it.
|
||||
, processIsDaemon ? true
|
||||
# Whether to disable logging the daemon process' output
|
||||
, enableDaemonOutputLogging ? true
|
||||
# Command-line arguments passed to the process.
|
||||
, args ? []
|
||||
# Path to a PID file that the system should use to manage the process. If null, it will use a default path.
|
||||
|
@ -137,6 +141,9 @@ let
|
|||
daemon = startProcessAsDaemon;
|
||||
user = _user;
|
||||
pidFile = _pidFile;
|
||||
outputLogFile = util.autoGenerateDaemonLogFilePath {
|
||||
inherit name instanceName logDir enableDaemonOutputLogging;
|
||||
};
|
||||
inherit process args pidFilesDir;
|
||||
};
|
||||
in
|
||||
|
|
|
@ -60,12 +60,23 @@ rec {
|
|||
else "${pidFilesDir}/${instanceName}.pid"
|
||||
else pidFile;
|
||||
|
||||
/*
|
||||
* Auto-generates the path to the log file that captures the
|
||||
* output of a process invoked with the daemon command
|
||||
*/
|
||||
autoGenerateDaemonLogFilePath = {name, instanceName, logDir, enableDaemonOutputLogging ? true}:
|
||||
if enableDaemonOutputLogging then
|
||||
if instanceName == null then "${logDir}/nixproc-${name}.log"
|
||||
else "${logDir}/nixproc-${instanceName}.log"
|
||||
else null;
|
||||
|
||||
/*
|
||||
* Creates a shell command invocation that deamonizes a foreground process by
|
||||
* using libslack's daemon command.
|
||||
*/
|
||||
daemonizeForegroundProcess = {daemon, process, args, pidFile ? null, pidFilesDir, user ? null}:
|
||||
daemonizeForegroundProcess = {daemon, process, args, pidFile ? null, pidFilesDir, user ? null, outputLogFile ? null}:
|
||||
"${daemon} --unsafe --inherit"
|
||||
+ (if outputLogFile == null then "" else " --output ${outputLogFile}")
|
||||
+ (if pidFile == null then " --pidfiles ${pidFilesDir} --name $(basename ${process})" else " --pidfile ${pidFile}")
|
||||
+ lib.optionalString (user != null) " --user ${user}"
|
||||
+ " -- ${process} ${lib.escapeShellArgs args}";
|
||||
|
|
Loading…
Reference in New Issue