diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-04-25 16:41:32 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-04-25 16:41:32 +0300 |
commit | d303c43cc5f6da65043147dbd9fe91756fe5d6fc (patch) | |
tree | 5ae8f69d7e785b72128964f0fbda9f8ad06e48e9 | |
parent | f997bbeb356818e9fc808dfe2ed803432aa1c870 (diff) | |
download | slb-d303c43cc5f6da65043147dbd9fe91756fe5d6fc.tar.gz slb-d303c43cc5f6da65043147dbd9fe91756fe5d6fc.tar.bz2 |
Improve docs.
* src/config.c: Implement the "default-expression" statement.
Rename "daemon" statement to "standalone".
* src/expr.y, src/slb.c, src/slb.h: Rename daemon_mode to
standalone_mode.
* doc/config.texi: Update.
* doc/slb.texi: Improve the tutorial.
-rw-r--r-- | doc/config.texi | 58 | ||||
-rw-r--r-- | doc/slb.texi | 392 | ||||
-rw-r--r-- | src/config.c | 36 | ||||
-rw-r--r-- | src/expr.y | 4 | ||||
-rw-r--r-- | src/slb.c | 8 | ||||
-rw-r--r-- | src/slb.h | 2 |
6 files changed, 459 insertions, 41 deletions
diff --git a/doc/config.texi b/doc/config.texi index b7af0dc..61e2cb4 100644 --- a/doc/config.texi +++ b/doc/config.texi @@ -449,12 +449,12 @@ print-priority yes; The following statements configure @command{slb} activities in daemon mode. -@deffn {Config} daemon bool - Enables or disables daemon mode. The daemon mode is enabled by -default. It is disabled either by setting +@deffn {Config} standalone bool + Enables or disables standalone daemon mode. The standalone mode is +enabled by default. It is disabled either by setting @example -daemon no +standalone no; @end example @noindent @@ -462,8 +462,9 @@ in the configuration file, or by using the @option{--cron} command line option (@pxref{option--cron}). @end deffn +@anchor{foreground statement} @deffn {Config} foreground bool -Do not detach from the controlling terminal. +Do not detach from the controlling terminal. @xref{option--foreground}. @end deffn @anchor{pidfile} @@ -472,6 +473,16 @@ Store master process @acronym{PID} in @var{file}. Default pidfile location is @file{/var/run/slb.pid}. @end deffn +@deffn {Config} wakeup number +Sets wake-up interval in seconds. SLB will recompute the server load +table each @var{number} seconds. +@end deffn + +@deffn {Config} suppress-output number +Suppress output during the first @var{number} wakeups. This statement +is reserved mostly for debugging purposes. +@end deffn + @node expression @section Expression @@ -485,12 +496,23 @@ Named expressions can be used as load estimation functions in @code{server} statements (@pxref{server, expression}) and invoked from the output format string (@pxref{output format}). -The @var{expr} is an arithmetical expression, which evaluates to a -floating point number. The expression consists of @dfn{terms}, -@dfn{function calls} and operators. The @dfn{terms} are floating -point numbers, variable and constant names. The names refer to -constants or SNMP variables defined in the definition of the server, -for which this expression is being evaluated. +@anchor{default-expression} +@deffn {Config} default-expression name +Declares the @dfn{default expression}. The @var{name} refers to a +named expression declared elsewhere in the configuration file. + +The default expression is used to compute relative load of servers +whose @samp{server} declaration lacks explicit @samp{expression} +definition (@pxref{server-expression}). +@end deffn + +The @var{expr} in the @samp{expression} statement is an arithmetical +expression, which evaluates to a floating point number. The +expression consists of @dfn{terms}, @dfn{function calls} and +operators. The @dfn{terms} are floating point numbers, variable and +constant names. The names refer to constants or SNMP variables +defined in the definition of the server, for which this expression is +being evaluated. The following operations are allowed in expression: @@ -708,16 +730,6 @@ round(-0.5) @result{} -1.0 @node SNMP configuration @section SNMP Configuration -@deffn {Config} wakeup number -Sets wake-up interval in seconds. SLB will recompute the server load -table each @var{number} seconds. -@end deffn - -@deffn {Config} suppress-output number -Suppress output during the first @var{number} wakeups. This statement -is reserved mostly for debugging purposes. -@end deffn - @deffn {Config} mib-directory dir Adds @var{dir} to the list of directories searched for the MIB definition files. @@ -779,9 +791,13 @@ timeout is reported. Sets SNMP community. @end deffn +@anchor{server-expression} @deffn {Config: server} expression string Defines the expression to compute relative load average of this server. @xref{expression}, for a description of the syntax of @var{string}. +If this statement is absent, the default expression will be used +(@pxref{default-expression}). If it is not declared as well, an error +is reported. @end deffn @deffn {Config: server} variable name oid diff --git a/doc/slb.texi b/doc/slb.texi index c16c32d..bd5e95e 100644 --- a/doc/slb.texi +++ b/doc/slb.texi @@ -89,6 +89,24 @@ Appendices @detailmenu --- The Detailed Node Listing --- +Tutorial + +* Option Basics:: +* Configuration Basics:: +* Daemon Configuration:: +* SNMP Configuration:: +* Server Definition:: +* Named Expressions:: + +SLB Command Line Syntax + +* program mode:: +* modifier options:: +* preprocessor control options:: +* logging control options:: +* debugging options:: +* informational options:: + SLB Configuration File * Syntax:: Configuration file syntax. @@ -108,7 +126,7 @@ Configuration file syntax Output Configuration -* output format:: Output Format String. +* output format:: Output Format String @end detailmenu @end menu @@ -173,6 +191,10 @@ familiar with the package. @menu * Option Basics:: * Configuration Basics:: +* Daemon Configuration:: +* SNMP Configuration:: +* Server Definition:: +* Named Expressions:: @end menu @node Option Basics @@ -185,7 +207,7 @@ interchangeable. @cindex options, short The @dfn{short} form is a traditional form for UNIX utilities. In this form, the option consists of a single dash, followed by a -single letter, e.g. @option{-c}. +single letter, e.g. @option{-c}. Short options which require arguments take their arguments immediately following the option letter, optionally separated by white @@ -194,7 +216,7 @@ Here, @option{-o} is the option, and @option{name} is its argument. Short options' letters may be clumped together, but you are not required to do this. When short options are clumped as a set, use one -(single) dash for them all, e.g. @option{-ne} is equivalent to @option{-n +(single) dash for them all, e.g. @option{-ne} is equivalent to @option{-n -e}. However, only options that do not take arguments may be clustered this way. If an option takes an argument, it can only be the last option in such a cluster, otherwise it would be impossible to @@ -232,9 +254,368 @@ explicitly inform @command{slb} about its actual location, using the slb --config-file ./new.conf @end example +@xopindex{lint, introduced} +Before actually starting the program, it is wise to check the +configuration file for errors. To do so, use the @option{--lint} +(@option{-t}) command line option: + +@example +slb --lint +@end example + +When started with this option, @command{slb} parses the configuration, +reports any errors on the standard error and exits. If the parsing +succeeds, it exits with code 0. Otherwise, if any errors have been +found, it exits with code 78 (@dfn{configuration error}). + +The @option{--lint} option can, of course, be used together with +@option{--config-file}, e.g.: -For a detailed discussion of configuration format, see -@ref{Configuration}. +@example +slb --lint --config-file ./new.conf +@end example + +@xopindex{config-help, introduced} +If you are unsure about the correct syntax, you can obtain a concise +summary any time, by running: + +@example +slb --config-help +@end example + +The summary is printed to the standard output and includes all +configuration statements with short descriptions of their purpose and +arguments. + +In this section we will provide a quick start introduction to the +@command{slb} configuration. For a more detailed and formal +discussion, refer to @ref{Configuration}. + +The configuration file consists of @dfn{statements}. There are two +kinds of statements, called simple and block statements. A @dfn{simple +statement} consists of a keyword and value, or values, separated by any +amount of whitespace and terminated with a semicolon, for example: + +@example +wakeup 15; +@end example + +A @dfn{block statement} is used for logical grouping of other +statements. It consists of a keyword, optionally followed by a value, +and a set of other statements, enclosed in a pair of curly brackets. +For example: + +@example +syslog @{ + facility local1; + tag slb; +@} +@end example + +A semicolon may follow the closing @samp{@}}, although this is not +required. + +Note that whitespace (i.e. space characters, tabs and newlines) has no +special syntactical meaning, except that it serves to separate +otherwise adjacent tokens. For example, the following form of the +@samp{syslog} statement is entirely equivalent to the one shown above: + +@example +syslog @{ facility local1; tag slb; @} +@end example + +Several types of @dfn{comments} are supported. A @dfn{single-line} +comment starts with @samp{#} or @samp{//} and continues to the end of +the line. A @dfn{multi-line} or @dfn{C-style} comment starts with the two +characters @samp{/*} (slash, star) and continues until the first +occurrence of @samp{*/} (star, slash). Whatever comment type are +used, they are removed from the configuration prior to parsing it. + +After comment removal, the configuration is @dfn{preprocessed} using +@command{m4}. This is a highly useful feature, which allows for +considerable simplification of configuration files. It is described +in @FIXME-ref{preprocessing}. + +@node Daemon Configuration +@section Daemon Configuration +The most importand daemon parameters are the operation mode and +wakeup interval. You are not required to explicitly configure them, +but you may want to do so, if their default values don't suit you. + +There are two @dfn{operation modes}: @samp{standalone} and +@samp{cron}. In standalone mode, @command{slb} detaches itself from +the controlling terminal and continues operation in the background, as +a @dfn{daemon}. It will periodically wake up, poll the servers, +compute the load table and format it to the output file or pipe. This +is the default operation mode. + +In @dfn{cron} mode, @command{slb} starts, polls the servers, computes +and formats the load table and exits when done. This mode is designed +for use from crontabs, hence its name. It has some limitation, +compared to the standalone mode. Most notably, the @code{d()} +function (derivative) is not available in this mode. + +@kwindex standalone +If you wish to explicitly set the operation mode, use the +@samp{standalone} configuration statement. The statement: + +@example +standalone yes; +@end example + +@noindent +configures the standalone mode, whereas the statement: + +@example +standalone no; +@end example + +@noindent +@xopindex{cron, introduced} +configures cron mode. The later can also be requested from the +command line, using the @option{--cron} option. + +@kwindex wakeup +When operating in standalone mode, the @dfn{wakeup interval} specifies +the amount of time, in seconds, between successive polls. The default +value is 5 minutes. To set another value, use the @samp{wakeup} +statement. For example, the following configures @command{sld} to do +a poll each minute: + +@example +wakeup 60; +@end example + +@node SNMP Configuration +@section SNMP Configuration +Normally, this does not require additional configuration, unless you +want to load some custom MIBs. + +@kwindex add-mib +To load an additional MIB file, use the @samp{add-mib} statement. Its +argument is the name of the file to load. + +@example +add-mib "MY-MIBS.txt"; +@end example + +@kwindex mib-directory +Unless full pathname is specified, the file is searched in the SNMP +search path. To modify the search path, use the +@samp{mib-directory}. Each @samp{mib-directory} adds a single +directory to the end of the path: + +@example +mib-directory "/usr/share/slb/mibs"; +@end example + +@node Server Definition +@section Server Definition +@dfn{Server definitions} are the principal part of any @command{slb} +configurations. They define remote servers for which @command{slb} +must compute the load table. A server definition is a block statement +which begins as: + +@example +server @var{id} @{ +@end example + +The @var{id} argument specifies @dfn{server ID}, an arbitrary +string of characters uniquely identifying this server. This ID will +be used by log messages concerning this server. It can also be +referred to in the output format definition (@FIXME-pxref{output +formats}). + +As usual, the definition ends with a closing @samp{@}}. + +Statements inside the @samp{server} block supply configuration +parameters for this servers. Two parameters are mandatory for +each server: its IP address and SNMP community: + +@kwindex host +@kwindex community +@example + host @var{ip}; + community @var{string}; +@end example + +The @var{ip} argument can be either the IP address of the server in +dotted-quad notation, or its host name. For example: + +@example + host 192.168.10.6; + community "public"; +@end example + +@kwindex expression +The most important part of a server definition is the expression used +to compute its relative load. It is basically an arithmetic +expression of arbitrary complexity, with SNMP variables serving as its +terms (@pxref{expression}). It is defined using the @samp{expression} +statement. + +To begin with, suppose you want to use the 1-minute load average as +relative load. Let's name it @samp{la1}. Then, the expression is +very simple and can be defined as: + +@example + expression "la1"; +@end example + +@kwindex variable +Now, @samp{la1} is a variable name, which should be bound to the +corresponding SNMP variable. This binding is declared with the +@samp{variable} statement: + +@example + variable la1 "UCD-SNMP-MIB::laLoadFloat.1"; +@end example + +The @samp{variable} statement has two arguments. The first one is the +name of a variable used in the expression and the second one is the +SNMP OID which is bound to this variable. This oid is added to the +list of OIDs queried during each poll of this server. When a SNMP +reply is received, all instances of that variable in the expression +are replaced with the value of the corresponding SNMP variable. Once +all variables have been thus resolved, the expression is evaluated and +its result is taken as the relative load for the given server. + +Let's take a more complex example. Suppose you define the relative +load to be a function of outgoing data transfer rate through the main +network interface and the load average of the server. Data transfer +rate is defined as first derivative of data transfer through the +interface with respect to time. Let's @samp{out} be the outgoing data +transfer, @samp{la1} be the server's 1-minute load average, @samp{k} +and @samp{m} be two server-dependent constants (@dfn{weight +coefficients}). Given that, we define relative load as + +@example + expression "sqrt(k * d(out)**2 + m * la1**2)"; +@end example + +The @samp{**} operator raises its left operand to the power given by +its second operand. The two constructs @samp{d(@dots{})} and +@samp{sqrt(@dots{})} are @dfn{function calls}. The @samp{d()} +function computes first derivative of its argument with respect to +time. The @samp{sqrt()} function computes the square root of its +argument. + +Now, let's define variable bindings: + +@example + variable out "IF-MIB::ifOutOctets.3"; + variable la1 "UCD-SNMP-MIB::laLoadFloat.1"; +@end example + +@kwindex constant +The @dfn{constants} @samp{k} and @samp{m} are defined using the +following statements: + +@example + constant k 1.5; + constant m 1.8; +@end example + +The @samp{constant} statement is similar to @samp{variable}, except +that its second argument must be a floating-point number. Of course, +in this particular example, the two constants could have been expanded +in the expression text, as in: + +@example + expression "sqrt(1.5 * d(out)**2 + 1.8 * la1**2)"; +@end example + +However, defining them on a per-server basis is useful when the +same expression is used for several different servers, as explained in +the following section. + +To conclude, here is our sample server definition: + +@example +server srv01 @{ + host 192.168.10.6; + community "public"; + expression "sqrt(k * d(out)**2 + m * la1**2)"; + variable out "IF-MIB::ifOutOctets.3"; + variable la1 "UCD-SNMP-MIB::laLoadFloat.1"; + constant k 1.5; + constant m 1.8; +@} +@end example + +@node Named Expressions +@section Named Expressions +@cindex named expressions +@cindex server context +In most cases, relative load is computed using an expression common for +all servers (perhaps with server-dependent set of coefficients and/or +variable bindings). To simplify configuration, such a common +expression can be defined once and then used by another @samp{server} +definitions. It can be defined as a @dfn{named expression}, i.e. an +expression that can be referred to by its name. + +Named expressions are defined using the @samp{expression} statement +outside of @samp{server} block. Such statements take two arguments: +the name of the expression and its definition, e.g.: + +@example +expression load "sqrt(k * d(out)**2 + m * la1**2)"; +@end example + +Named expressions can be @dfn{invoked} from another expressions using +the @samp{@@} operator, followed by expression's name. For example, +the following statement in @samp{server} block: + +@example + expression "@@load"; +@end example + +@noindent +is in fact equivalent to the expression defined above. The @samp{@@} +construct can, of course, also be used as a term in arithmetic +calculations, e.g.: + +@example + expression "2 * @@load + 1"; +@end example + +@anchor{default expression} +@kwindex default-expression +A @dfn{default expression} is a named expression which is implicitly +applied for @samp{server} statements that lack @samp{expression} +statement. Default expression is defined using the +@samp{default-expression} statement: + +@example +default-expression "load"; +@end example + +To finish this section, here is an example configuration declaring two +servers using the same default expression, but supplying different +sets of coefficients: + +@example +expression load "sqrt(k * d(out)**2 + m * la1**2)"; +default-expression "load"; + +server srv01 @{ + host 192.168.10.6; + community "public"; + variable out "IF-MIB::ifOutOctets.3"; + variable la1 "UCD-SNMP-MIB::laLoadFloat.1"; + constant k 1.5; + constant m 1.8; +@} + +server srv02 @{ + host 192.168.10.1; + community "private"; + variable out "IF-MIB::ifOutOctets.3"; + variable la1 "UCD-SNMP-MIB::laLoadFloat.1"; + constant k 2.5; + constant m 2.2; +@} +@end example @node Invocation @@ -344,6 +725,7 @@ exit with code 0, if the syntax is OK, and with code 1 otherwise. @opsummary{foreground} @item --foreground Remain in the foreground. Useful for debugging purposes. +@xref{foreground statement}. @opsummary{output-file} @sopindex{o, summary} diff --git a/src/config.c b/src/config.c index f5b80a5..9721935 100644 --- a/src/config.c +++ b/src/config.c @@ -20,6 +20,7 @@ gl_list_t mib_file_list; struct slb_server *srv_head, *srv_tail; size_t srv_count; +char *default_expression; void register_server(struct slb_server *srv) @@ -452,11 +453,6 @@ cb_server(enum grecs_callback_command cmd, _("server name not defined")); return 1; } - if (!srv->expr) { - grecs_error(locus, 0, - _("server expression not defined")); - return 1; - } register_server(srv); *pdata = NULL; break; @@ -507,8 +503,8 @@ static struct grecs_keyword syslog_kw[] = { static struct grecs_keyword slb_kw[] = { - { "daemon", NULL, N_("Enable daemon mode"), - grecs_type_bool, &daemon_mode }, + { "standalone", NULL, N_("Enable standalone mode"), + grecs_type_bool, &standalone_mode }, { "foreground", NULL, N_("Start in foreground even in daemon mode"), grecs_type_bool, &foreground }, { "pidfile", N_("file"), N_("Set pid file name"), @@ -533,6 +529,10 @@ static struct grecs_keyword slb_kw[] = { N_("define a named expression"), grecs_type_string, NULL, 0, cb_define_expression }, + { "default-expression", NULL, + N_("Set the name of the default expression"), + grecs_type_string, &default_expression }, + { "server", N_("id: string"), N_("Define a server"), grecs_type_section, NULL, 0, cb_server, NULL, server_kw }, @@ -623,7 +623,8 @@ config_finish() { struct slb_server *srv; gl_list_iterator_t itr; - + struct slb_expression *defexpr = NULL; + init_mib(); /* Load requested MIBs */ @@ -640,7 +641,26 @@ config_finish() collect_output_refs(); + if (default_expression) { + defexpr = expression_lookupz(default_expression); + if (!defexpr) { + grecs_error(NULL, 0, + _("default-expression refers to " + "undefined expression")); + exit(EX_CONFIG); + } + } + for (srv = srv_head; srv; srv = srv->next) { + if (!srv->expr) { + if (defexpr) + srv->expr = copy_expression(defexpr, NULL); + else { + grecs_error(&srv->locus, 0, + _("server expression not defined")); + continue; + } + } if (fixup_expression(srv->expr, srv->varinst)) srv->flags |= SLB_SRV_DISABLED; else { @@ -52,9 +52,9 @@ request_daemon_mode_hook(void *ptr) { struct daemon_only_closure *clos = ptr; - if (!daemon_mode) { + if (!standalone_mode) { grecs_error(&clos->locus, 0, - "function %s can be used only in daemon mode", + "function %s can be used only in standalone mode", clos->func->name); return 1; } @@ -21,7 +21,7 @@ int lint_mode; int debug_level[_SLB_DEBCAT_MAX]; int dry_run_mode; int preprocess_only = 0; -int daemon_mode = 1; +int standalone_mode = 1; int foreground; int foreground_option; int cron_option; @@ -425,7 +425,7 @@ main(int argc, char **argv) exit(EX_CONFIG); if (cron_option) - daemon_mode = 0; + standalone_mode = 0; config_finish(); @@ -457,11 +457,11 @@ main(int argc, char **argv) if (output_file_option) output_file = output_file_option; - if (daemon_mode) { + if (standalone_mode) { slb_daemon(); } else { if (log_to_stderr == -1) { - log_to_stderr = (!daemon_mode || foreground) && + log_to_stderr = (!standalone_mode || foreground) && isatty(0); logger_setup(); } @@ -62,7 +62,7 @@ void config_finish(void); typedef int (*config_finish_hook_t)(void *); void add_config_finish_hook(config_finish_hook_t fun, void *data); -extern int daemon_mode; +extern int standalone_mode; extern int foreground; extern char *pidfile; extern time_t wakeup_interval; |