{= include("docs.util"); start_docs_page("The Configuration Language"); =}
Salang is the programming $PRODUCT_NAME language, which is used throughout $PRODUCT_NAME for many purposes from displaying pages like this one, including administrative or statistics pages, to writing log filters.
Salang is similar in some ways to perl, and borrows syntactic elements from perl, C, and other languages. Because Salang code is intended to be written inline, rather than as a stand-alone program, it deviates from perl and C in various ways, including the use of parentheses instead of brackets to group statements and expressions. Programmers acquainted with perl or C will find themselves in familiar territory with Salang.
Operator | Purpose |
== | Compares two numbers; true if they are equal; e.g. 1 == 1 is true. |
!= | Compares two numbers; true if they are not equal; e.g. 1 != 1 is false. |
<= | Compares two numbers; true if the left number is less than or equal to the right; e.g. 1 <= 2 is true, and so is 1 <= 1. |
>= | Compares two numbers; true if the left number is greater than or equal to the right; e.g. 2 >= 1 is true, and so is 1 >= 1. |
< | Compares two numbers; true if the left number is less than the right; e.g. 1 < 2 is true, but 1 < 1 is false. |
> | Compares two numbers; true if the left number is greater than the right; e.g. 2 > 1 is true, but 1 > 1 is false. |
eq | Compares two strings; true if they are equal; e.g. "a" eq "a" is true. |
ne | Compares two strings; true if they are not equal; e.g. "a" ne "a" is false. |
le | Compares two strings; true if the left string is lexically less than or equal to the right; e.g. "a" le "b" is true, and so is "a" le "a". |
ge | Compares two strings; true if the left string is lexically greater than or equal to the right; e.g. "b" ge "a" is true, and so is "a" ge "a". |
lt | Compares two strings; true if the left string is lexically less than the right; e.g. "a" lt "b" is true, but "a" lt "a" is false. |
gt | Compares two strings; true if the left string is lexically greater than the right; e.g. "b" gt "a" is true, but "a" gt "a" is false. |
or | True if either left or right values, or both, are true; e.g. true or true is true; true or false is true. |
and | True if both left and right values are true; e.g. true and true is true; true and false is false. |
+ | Adds the right value to the left value; e.g. 1+2 is 3. |
- | Subtracts the right value from the left value; e.g. 2-1 is 1. |
* | Multiplies the right value and the left value; e.g. 2*3 is 6. |
% | Modulo (division remainder) operation on the left value by the right value; e.g. 5%2 is 1 and 6%2 is 0. |
/ | Divides the left value by the right value; e.g. 12/4 is 3. |
+= | Adds the right value numerically to the left variable; e.g. x += 1 adds 1 to x. |
-= | Subtracts the right value numerically from the left variable; e.g. x -= 1 subtracts 1 from x. |
++ | Adds 1 numerically to the left variable; e.g. x++ adds 1 to x. |
-- | Subtracts 1 numerically from the left variable; e.g. x-- subtracts 1 from x. |
. | Concatenates the right string to the end of the left string; e.g. "a"."b" is "ab". |
.= | Concatenates the right value to the left variable; e.g. x .= "X" concatenates "X" to the end of x. |
= | Assigns the right hand side to the left hand side; e.g. x = 1 assigns a value of 1 to the variable x. |
! | Performs a boolean negation ("not" operation) of its unary parameter; e.g. !true is false, and !false is true. |
not | Same as ! |
matches | True if the left value matches the wildcard pattern specified by the right value. |
matches_regexp | True if the left value matches the regular expression specified by the right value. |
within | Used in report filtering; true if the value of the database field specified by the left value is within the value specified by the right value; e.g. page within '/directory/'. |
%24 | Treats its unary string parameter as a variable name, and evaluates the value of the variable; e.g. if the value of the variable named "somevariable" is 1, then the value of the expression %24("somevariable") is 1. Important: This uses the value of the expression immediately after it as the name of the variable, so if variable x has value "valueX" then %24x means the same as %24("valueX"); i.e. it is the value of the variable valueX, not the value of the variable x. To get the value of the variable x, just use x, not %24x. |
Single quotes ('), double quotes (") and backticks (`) can be used as quotes. Quotes are "smart"--you can use one type of quotes within another type of quotes, e.g. v = "someone's value". If you need to use the same types of quotes, you can use a backslash, e.g. v = 'someone\'s value'. Backslashes can be used to escape other characters, including dollars signs in values, to prevent them from being treated as variable evaluation operators.
Variables and other data are stored in the configuration hierarchy, a collection of data which exists on disk and partially in memory. The configuration hierarchy is a group of "nodes", each with a single value. Any node can also contain other nodes (subnodes). Each node has a type ("bool", "int", "float", "string", or "node"), and a value. Salang expressions can get values from the hierarchy (e.g. "internal.verbose" is an expression which gets the value of the "verbose" subnode of the "internal" node), or set them (e.g. "internal.verbose = 1;").
Configuration nodes are referenced using a dot-separated (.) sequence of names, which functions like a pathname. Configuration nodes are grouped hierchically either using sub$lang_stats.directories, or by using configuration group files (.cfg files). The .cfg files have additional hierarchical groupings within them, specified by curly-bracketed groups. For instance, the node name "rewrite_rules" refers to the rewrite_rules $lang_stats.directory of LogAnalysisInfo, and the node name "rewrite_rules.server_responses" refers to the server_responses.cfg file, in the rewrite_rules $lang_stats.directory of LogAnalysisInfo. The server_responses.cfg file looks like this:
server_responses = { 100 = { regexp = "100" result = "Continue" } ... 200 = { regexp = "200" result = "Successful Transfer" } ... } # server_response
The series of three of dots (...) as shown above are ellipses and they indicate places where part of the file has been omitted for brevity, so there is a "100" node inside the server_responses node, and there is also a "200" node there. Therefore, the node name "rewrite_rules.server_responses.100" refers to the 100 node, and "rewrite_rules.server_responses.200" refers to the 200 node. Within the 100 node, there are two nodes, "regexp" and "result"; so "rewrite_rules.server_responses.100.regexp" refers to the regexp node in 100, and "rewrite_rules.server_responses.200.regexp" refers to the regexp node in 200.
Directories are treated equivalently to .cfg files in the configuration hierarchy. In both cases, they represent nodes, and can contain other nodes. In the case of directories, subnodes appear as subdirectories, or as .cfg files in the directory, or as configuration value files (.cfv files) in the directory; in the case of .cfg files, subnodes appear within the file using curly-bracket syntax, as above.
As mentioned above, every node has a value. In the example above, the value of rewrite_rules.server_responses.200.regexp is "100", and the value of rewrite_rules.server_responses.100.result is "Continue". Even group nodes like rewrite_rules.server_responses.100, rewrite_rules.server_responses, and rewrite_rules can have values, but their values are typically empty (""); a node has either a value, or subnodes.
Nodes can be used like variables (they are variable). Nodes can be referred to by name, in log filters or other Salang code; for instance this:
echo(rewrite_rules.server_responses.100.result)
will print the value "Continue" to the standard output stream. They can also be assigned values:
rewrite_rules.server_responses.100.result = "Something Else"
Nodes are read from disk into memory automatically when they are accessed, and the in-memory version is used for the remainder of the process, and then discarded. Therefore, it is not generally necessary to read data from disk explicitly; instead, put it in a node and access it by name. In the example above, the value of rewrite_rules.server_responses.100.result will be temporarily changed to "Something Else"; only the in-memory version of rewrite_rules.server_responses.100.result will change, and the change will not be propagated to disk unless {=docs_function_link('save_node')=} is used to write out the changes back out to disk.
Configuration value files (.cfv files) are straight text files whose entire content is considered to be the string value of the node. For example, the file LogAnalysisInfo/somedir/somefile.cfv whose contents is "HELLO" could be referred to as somedir.somefile; the value of that node is "HELLO".
Salang has a built-in type of node
that refers to a configuration node; it is a pointer to that node.
You can get the value of the node using {=docs_function_link('node_value')=}. You can also get a particular subnode
using {=docs_function_link('subnode_by_name')=}. You can check for the existence of a subnode using
{=docs_function_link('subnode_exists')=} or use {=docs_function_link('node_exists')=} with the full nodename as the parameter.
In addition to the LogAnalysisInfo directory, Salang also looks in other "search paths" to find nodes specified by name:
If the node name begins with lang_, it will search for it in LogAnalysisInfo/language/{current} where {current} is the current language. For instance, if the current language is "english", then the node "lang_stats.menu.groups.date_time_group" refers to the date_time_group node, in the groups node, in the menu node, in the LogAnalysisInfo/languages/english/lang_stats.cfg.
If a profile is active (e.g. was specified with -p on the command line), it will search for the node in the profile .cfg file. For instance, if $PRODUCT_NAME is called with -p myprofile, then the node "database.fields.date_time" refers to the date_time database field, and "database_fields.date_time.label" refers to the label for the date_time database field.
In log filters, if the node name is exactly the name of a log field, then the log field value is used. This is not actually a node, but functions as one for the purpose of reading and writing its value; you can refer to it like a normal Salang variable in most cases (e.g., "file_type = 'GIF'").
If a local variable has been declared in Salang, it can be referred to by name. For instance, you can write:
int i; i = 3; echo(i);
to define and refer to a local variable node i. Local variables do not have full nodenames; they are free-floating in memory and cannot be saved to disk, they are refered to as not being "rooted" in LogAnalysisInfo like most other nodes. They can only be referred to by their short nodenames (e.g. "i").
Inside subroutines, the subroutine parameters can be referred to by name. For instance, the following subroutine, which adds two numbers, refers to its parameters x and y directly:
subroutine(add(int x, int y), ( x + y ));
Subroutine parameters are similar to local variables (above) in that they are not rooted, and cannot be written to disk.
The special variables \$0, \$1, \$2, etc. refer to the matched subexpressions of the last call to {=docs_function_link('matches_regular_expression')=}.
Filters used in reports take a special variant syntax that allows only certain operations. Subroutines (described below) are not allowed, and only database field names are allowed as variables. Only strings are allowed as constants. The <, >, <=, and => operators are permitted for the date_time field only. The "within", "matches", and "matches_regexp" operators are permitted for any field. Expressions can be combined using "and", "or", and "not"; arbitrary parentheses are permitted to allow any combinations. No other syntax is permitted.
Log filters can use all syntax described on this page, and also support a few extra variables. Specifically, log filters can refer to log fields by name, so a reference to date_time in a log filter is a reference to the value of the date_time field in the log entry that is currently being processed. This can be used either to get or set values; e.g. "if (page eq '/index.html') then 'reject'" checks the current log entry's page field to see if it's "/index.html", and rejects the log entry if it is; and "page = '/index.html'" sets the page field of the current log entry to "/index.html".
Log filters can also use the special function current_log_line(), whose value is the entire current line of log data.
Each configuration node has a type, which specifies how its data is stored internally. Possible types are:
string
: The data is an arbitrary string value like "hello" or "Bob".
int
: The data is an integer value like 15 or 49.
float
: The data is a floating point value like 1.4 or 18874.46567.
bool
: The data is a boolean value (true or false).
node
: The data is a reference (pointer) to a node in the configuration hierarchy.
Types are primarily useful for performance optimization. Salang is a weakly typed language, so it will allow
any value to be assigned to any variable without warning or complaint; for instance assigning 134 to
a string
variable will result in "134" in the string
variable, or assigning "134.5" to a float
variable
will result in the floating point value of 134.5 in the float
variable. However, these types of conversions
can be slow if they are performed many times, so if you know a variable is only going to hold and manipulate
floating point values, you should use a float
type rather than a string
type.
The node
type is particularly useful for performance optimization, since it prevents the need for
node lookups; e.g. setting the value of a node explicitly with "a.b.c.d = 0;
" requires a series of expensive lookups,
as node "a" is looked up in the configuration root, and then "b" inside that, and then "c", and then "d"-- but if
a node
variable N already points to a.b.c.d, then "N = 0;" is a very fast operation that does the same thing.
node
variables are particularly useful for foreach
loops, and functions like subnode_value(),
where they can be used to iterate over all subnodes without requiring any performance intensive string-to-node lookups.
if A then B else C
This statement evaluates the A section; if the value of A is true, then the value of the entire statement is the B section;
otherwise, the value of the statement is the C section.
subroutine(A(param1, param2, ..., paramN), B)
This statement defines a subroutine A with N parameters. The subroutine can be called with the statement "A(p1, p2, ..., pN)".
The value of the subroutine call will be the value of B, with the parameters p1...pN plugged into the variables %24param1..%24paramN
before B is evaluated. The value of a subroutine declaration is empty.
foreach I N B
This statement is used to iterate over the subnodes of a particular node in the Salang hierarchy. It iterates over all values
of node N, setting I to the full nodepath each iteration, and then evaluating expression B. The value of this expression is
the concatenation of the values of all the evaluations of B.
for (I; C; E)
This repeats an expression 0 or more times.
The expression I is evaluated to initialize the loop.
The expression C is evaluated, before each iteration, and if the result is false, then the iteration does not complete.
If C is true, the E is evaluated. The value of this expression is the concatenation of the E values.
while (C) E;
This repeats an expression 0 or more times.
The expression C is evaluated before each iteration, and if the result is true, then E is evaluated. This continues
until C is false. The value of this expression is the concatenation of the E values.
next
This statement goes immediately to the next iteration of the immediately enclosing loop.
last
This statement immediately terminates execution of the immediately enclosing loop, and continues execution after the end of the loop.
get_file_type_from_url(string U)
The value of this statement is the file extension of the URL U; e.g., get_file_type_from_url("http://something/file.gif")
is "GIF".
get_log_field(string N)
Returns the value of the log field N, of the current log entry.
node_exists(string N)
Returns true if the node specified by the nodename N exists; false if the node does not exist.
node_name(node N)
Returns the name of the node N.
num_subnodes(node N)
Returns the number of subnodes of the node specified by nodename N.
subnode_by_number(node N, int I)
Returns the Ith subnode of node N.
subnode_by_name(node N, string M)
Returns the subnode of node N whose name is M. If there is no subnode by that name, it creates one.
subnode_exists(node N, string M)
Returns true if there is a subnode named M in node N, false otherwise.
set_subnode_value(node N, string M, anytype V)
Sets the subnode named M of node N to the value V. Creates the subnode if it does not exist.
node_value(node N)
Returns the value of node N.
set_node_value(node N, anytype V)
Sets the value of node N to V; no value is returned.
node_type(node N)
Returns the type of node N as a string : e.g., "int", "float", "bool", "string", or "node".
set_node_type(node N, string T)
Sets the type of node N to T: e.g., "int", "float", "bool", "string", or "node".
delete_node(node N)
Deletes the node specified by nodename N. If the node is a profile, this also deletes the
profile file.
insert_node(node P, string N, int I)
Inserts the node specified by nodename N into the node specified by nodename P, so that N ends up as
the Ith subnode of P (i.e., it inserts N into P at position I). N is removed from its current location,
and moved to the new one, so for instance if N is a subnode of O before this is called, it will no longer
be a subnode of O afterwards
; i.e., it moves N, rather than copying it.
clone_node(node original_node, string clone_nodepath)
This makes a clone of the node original_node, and puts it at the node specified by
clone_nodepath (which is created if it doesn't exist). The original node is unchanged,
and after completion, the clone is an exact replicate of the original, except the name (which
is computed from clone_nodepath).
sort(node N, string M, bool E)
Sorts the subnodes of the node specified by nodename N. The subnodes are sorted in an order specified
by method M. M is a string of the format "field:F,T,A", where F is a field name (the name of a subnode found
in each subnode of N; use "value" to use the value of each subnode of N directly),
T is "integer", "float", "alphabetical", or "chronological" (which determines the sort type),
and A is "ascending" or "descending"
(which determine the direction of sort).
If E is true, then variable are expanded before sorting; if E is false, then the sort is done on the literal
values, without variable expansion.
create_profile(string N)
This creates a new profile with name N. It pulls various variables from the node hierarchy to set up
the profile, the nodes are set by the "create profile" interview.
format(anytype V, string T)
This formats the value V according to the format type T. T can be "integer", "page", "float", "two_digit_fixed", "bandwidth",
"date_time", "hostname", "duration", "duration_compact", or "duration_milliseconds".
If the first character of T is a % character, the result will be formatted as a double-precision floating
point number using printf-style formatting, e.g. '%.1f' will print the value in floating point format
with one digit after the decimal place.
image(string N, int W, int H)
The value of this subroutine is an HTML image tag which displays the image specified by filename N,
with width W and height H. The image file should be in the temporary directory in CGI mode, or
in the picts folder, which is in the WebServeRoot folder of the LogAnalysisInfo folder, in web server mode.
create_image(int width, int height)
This creates a new image canvas of the specified image and height, and returns the image ID for use in drawing
functions. It returns the image ID for use in drawing functions.
allocate_image_color(string imageid, int red, int green, int blue)
This allocates a new color for use in drawing on image imageid (created by create_image()),
with the specified red, green, and blue components (0 to 255). It returns the color value for use in drawing functions.
add_text_to_image(string imageid, string color, int x, int y, string text, string direction)
This draws text on image imageid (created by create_image()), with the specified color (created with
allocate_image_color()) at the specified x and y position, in the directory specified by direction
("up" or "right"). The upper left corner of the text will be anchored at (x, y) when drawing horizontally;
the lower left corner will be anchored there when drawing vertically.
add_line_to_image(string imageid, string color, int x1, int y1, int x2, int y2)
This draws a line on image imageid (created by create_image()), with the specified color (created with
allocate_image_color()) from the point (x1, y1) to the point (x2, y2).
add_polygon_to_image(string imageid, string color, node points, bool filled)
This draws a polygon on image imageid (created by create_image()), with the specified color (created with
allocate_image_color()). The vertices of the polygon are specified in order in the subnodes of points; each
subnode must have an x and a y value specifying the location of that point.
The polygon will be a single pixel border if filled is false, or filled if it is true.
add_rectangle_to_image(string imageid, string color, int xmin, int ymin, int xmax, int ymax, bool filled)
This draws a rectangle on image imageid (created by create_image()), with the specified color (created with
allocate_image_color()) and minimum x/y dimensions. The rectangle will be a single pixel border if filled
is false, or filled if it is true.
write_image_to_disk(string imageid, string pathname)
This writes the image imageid (created by create_image()) to disk as a GIF file, to the location
specified by pathname.
img_src(string N)
The value of this subroutine is the value of an HTML src section of an image tag; i.e. it's intended
to be used right after src= in an image tag.
The image file should be in the temporary directory in CGI mode, or
in the picts folder, which is in the WebServeRoot folder of the LogAnalysisInfo folder, in web server mode.
fileref(string F)
This converts a local filename from the WebServerRoot directory to a URL that refers to that file.
The filename should be in partial URL syntax, e.g. "picts/somefile.gif" to refer to the file somefile.gif
in the picts directory of WebServerRoot.
If necessary, it may copy the file; e.g., in CGI mode to the temporary directory.
All references to files in WebServerRoot should be done through this function to ensure
correct functioning in CGI mode.
save_changes()
This causes any changes made to the configuration hierarchy since the last save
to be saved to the disk version of the hierarchy.
save_node(node N)
This saves node N to disk. For instance, if a N is "somenode.somechild.somevar", this will
be saved to a file called somevar.cfg, in the somechild $lang_stats.directory of the somenode $lang_stats.directory
of the LogAnalysisInfo $lang_stats.directory. The format used is normal configuration format.
This makes the node persistent, because any future access to that node; e.g., referring to somenode.somechild.somevar
in an expression, even from a later process after the current one has exited, will automatically load the node value from disk.
So by using save_node(), you can ensure that any changes made to that node will be a permanent part of the configuration hierarchy,
and any values you have set will be available for use to all future processes and threads.
logout()
This logs the current user out (clearing the cookies that maintained their login),
and takes them back to the login page (or the logout URL, if one is specified).
expand(string M)
This expands variables and expressions in M, and returns the expanded value. For instance,
expand("%24x") will return the value of the variable x,
and expand("%24x > %24y") will return "12 > 10", if x is 12 and y is 10.
convert_escapes(string M)
This converts percent-sign escape sequences in M (e.g. converting %2520 to a space),
and returns the converted value. For instance,
expand("some%2520string") will return "some string".
set_active_profile(string profile_name)
This sets the active profile to profile_name. The specified profile will be searched when
looking up variables; e.g. the variable database.fields.date_time.label (which would normally be invalid,
if no profile were active) will be treated as a local nodename within the specified profile, and be resolved
as though it were profiles. profile_name. database.fields.date_time.label.
debug_message(string M)
This converts variables and expressions in M, and displays the resulting value
to the standard debug stream; i.e., to the console.
This is useful for debugging Salang code.
echo(string M)
This outputs the string M (without any conversion) directly to the standard output stream.
This is useful for debugging Salang code.
error(string M)
This throws an error exception, with error message M. The error will be reported through the standard
$PRODUCT_NAME error reporting mechanism.
node_as_string(node N)
This converts the node N as a string value (like you would see it in a profile file).
The value of this expression is the string value of N.
node string_to_node(string s)
This converts the string s to a node, and returns the node. This is similar to
writing the string to a .cfg file, and reading it in as a node. For instance,
string_to_node("x = { a = 1 b = 2 }") will return a node whose name is x, which has two subnodes a and b,
with values 1 and 2.
autodetect_log_format(node log_source, string result, string id)
This autodetects the log format from the log source log_source, and puts the result in the node specified by result.
id is an identifier which appears in the task info node for this process, allowing another process to tap into the progress
for this process.
This is used internally by the profile creation wizard.
get_directory_contents(string P, string R)
This gets the contents of the directory at pathname P, and puts the result in the node specified by R.
R will contain a subnode for each file or subdirectory, and within each subnode there will be a name
node listing the name of the file or directory and an is_directory
node which is true for a directory
or false for a file; there will also be a size
node if it's a file, listing the file size in bytes.
get_file_info(string P, string R)
This gets information about the file or directory at pathname P, and puts the result in the node specified by R.
R.exists will be true or false depending on whether P exists;
R.parent will be the full pathname of the parent of P;
R.type will be "file" or "directory" depending on whether P is a file or directory;
R.filename will be the filename or directory name of P.
file_exists(string P)
The value of this is true or false, depending on whether the file or directory at pathname P exists.
delete_file(string pathname)
This deletes the file whose location is specified by pathname.
delete_directory(string pathname)
This deletes the directory whose location is specified by pathname, including all subdirectories and files.
get_files_matching_log_source(node L, string R)
This gets a list of files matching the log source in node L, and puts the result in the node specified by R.
R will contain a subnode for each matching file; the value of the subnode will be the filename.
This is used by the interface to implement Show Matching Files.
length(string S)
The value of this expression is the length of the string S.
substr(string V, int S, int L)
The value of this expression is the substring of the string V, starting at index S and of length L.
The L parameter is optional, and if it is omitted, the value of the expression is the substring of V starting at S
and continuing to the end of V.
split(string s, string divider, string resultnode)
This splits the string s on the divider specified in divider, and puts the resulting sections into
the node specified by resultnode. For instance, split("Hello,you,there", ",", "volatile.splitresult") will
set volatile.splitresult.0 to "Hello", volatile.splitresult.1 to "you", and volatile.splitresult.2 to "there".
starts_with(string S, string T)
The value of this expression is true if the string S starts with the value of the string T.
ends_with(string S, string T)
The value of this expression is true if the string S ends with the value of the string T.
contains(string S, string T)
The value of this expression is true if the string S contains the value of the string T.
replace_all(string S, string T, string R)
The value of this expression is the value of S after all occurrences of T have been replaced with R.
replace_first(string S, string T, string R)
The value of this expression is the value of S after the first occurrence of T has been replaced with R.
If T does not occur in S, the value of this expression is S.
replace_last(string S, string T, string R)
The value of this expression is the value of S after the last occurrence of T has been replaced with R.
If T does not occur in S, the value of this expression is S.
lowercase(string S)
The value of this expression is the value of S after all uppercase letters have been converted to lowercase.
uppercase(string S)
The value of this expression is the value of S after all lowercase letters have been converted to uppercase.
convert_charset(string value, string fromcharset, string tocharset)
This converts the string value from the charset fromcharset to the charset tocharset.
It returns the converted version of value. Charset names are as documented for the GNU iconv
conversion utility.
convert_local_code_page_to_utf8(string value)
This converts the string value from the local code page (local operating system charset) to the UTF-8 charset.
It returns the converted version of value.
convert_utf8_to_local_code_page(string value)
This converts the string value from the UTF-8 charset to the local code page (local operating system charset).
It returns the converted version of value.
get_search_engine_info(string url)
This examines url to see if it matches any of the search engine rules in the search_engines.cfg file in LogAnalysisInfo.
If it does, it sets volatile.search_engine and volatile.search_phrase to the matching search engine and search phrase.
matches_regular_expression(string S, string R)
The value of this expression is true if the string S matches the regular expression R.
If it matches, the variables %240, %241, %242, ... are set to the substrings of S which match the parenthesized
subexpressions RE.
matches_wildcard_expression(string str, string wildcardexp)
The value of this expression is true if the string str matches the wildcard expression wildcardexp.
index(string S, string T)
The value of this expression is the index (character position) of the substring T in the string S.
If T is not a substring of S, the value of this expression is -1.
last_index(string S, string T)
The value of this expression is the index (character position) of the final occurrence of substring T in the string S.
If T is not a substring of S, the value of this expression is -1.
md5_digest(string S)
The value of this expression is the MD5 digest of the string S, as a 32-digit hexadecimal number.
get_license_info(node licensenode, node resultnode)
This looks at the $PRODUCT_NAME license key contained in licensenode, and extracts information about it,
which it puts in the node pointed to by resultnode. The subnodes of the result are type,
valid, valid64, valid65, addon, expiration, profiles, and users.
string create_trial_license()
This creates and returns a 30-day trial license key. Only one trial key can be generated per installation;
after the first time, it will return an empty string.
node license_string_to_license_node(string license_string)
This converts a string format license key (license_string) into a node format license key.
It returns the node key is returned. If the string is not valid, the node will not contain a checksum,
and will have valid=false as a subnode.
display_statistics_filters(node F, string D)
The value of this expression is HTML which describes the Filters in node F, for database field D.
This is used internally by the statistics interface to display Filters.
query_one_db_item(node F, string R)
This queries the numerical database field totals for the Filters F, and puts the result in the node R.
query_db_for_view(node V, string R)
This queries the database for statistics view V, and puts the result in R.
The format of R depends on the type of the view V.
Also, if volatile.csv_export is true, this computes a CSV version of the query result,
and puts it in volatile.csv_export_result.
query_db_calendar(string R)
This queries the database to compute calendar information (which days are in the database),
and puts the result in R. R contains a numerical year node for each year, and within that a numerical
month node for each month, and within that a numerical day node for each day in the database.
query_db_field_hierarchy(string dbfieldname, string nodename)
This queries the database to compute the hierarchy of the database field dbfieldname,
and puts the result in nodename. The values of nodes in nodename match the values of items for that database field,
and the hierarchical structure of nodename exactly matches the structure of the field.
db_item_has_subitems(string D, string I)
This checks whether item I of database field D has subitems in the current database.
It returns true if it does, and false if it isn't (i.e. if it's a bottom-level item).
set_log_field(string N, string V)
This sets the value of the log field N of the current log entry to V.
include(node N)
This loads and processes the Salang code in the node specified by nodename N.
discard(anytype V)
The value of this expression is always empty (""). This is useful if you want to evaluate
an expression V, but not use its value.
capitalize(string V)
This capitalizes the value V, using the capitalization rules in the language module.
pluralizes(string V)
This pluralizes the value V, using the pluralization rules in the language module.
char_to_ascii(string c)
This returns the integer ASCII code of the character c. c should be a one-character string.
ascii_to_char(int i)
This returns a one-character string containing the ASCII character whose code is i.
ip_address_to_int(string ipaddr)
This converts the IP address ipaddr to an integer (a 32-bit representation with 8 bits per octet).
convert_field_map(string F, string M)
This converts the value of the log field F in the current log line we're processing, using the map M.
M is a |-divided list of A->B mappings; e.g., if M is "1->cat|2->dog|3->ferret", then a field value
"2" will be converted to "dog".
collect_fields_using_regexp(string R, string F)
This matches the current log line we're processing against the regular expression R, and if it matches,
it extracts the parenthesized values in R and puts them in the fields specified by F. F is a comma-separated
list of fields, and should include *KEY*, which specifies the key of the collected log entry to modify.
E.g., if F is "page,*KEY*,date_time,host", the second parenthesized subexpression will be used as the key,
and that key will specify which collected entry to modify; then the page, date_time, and host fields of that
collected entry will be set to the first, third, and fourth parenthesized sections.
collect_listed_fields_using_regexp(string regexp, string divider, string separator, string field_names_map)
This matches the current log line we're processing against the regular expression regexp, and if it matches,
it uses the first parenthesized section in regexp and uses that as the key, and uses the second parenthesized
section and uses it as the name/values list. Then it uses that, and its other parameters, to do the same as
collected_listed_fields().
collect_listed_fields(string key, string name_values_list, string divider, string separator, string field_names_map)
This extracts log field values from name_values_list, which is a list of name/values pairs, and puts them in the collected entry specified by key. Names and values are listed in name_value_list the format "name1separatorvalue1dividername2separatorvalue2dividername3separatorvalue3", e.g. pairs are separate from each other by the value of divider, and each name is separate from its value by the value of separator. In addition, field_names_map can be used to convert field names; field_names_map is a pipe-separated (|-separated) list of values like "fieldname=newfieldname", and if any extracted field matches a fieldname value from field_names_map, it will be put in the newfieldname log field. If there is no map, or if nothing matches, then values will be put in the log field specified by the field name.
accept_collected_entry_using_regexp(string R)
This matches the current log line we're processing against the regular expression R, and if it matches,
it extracts the first parenthesized value in R; using that value as a key field, it accepts the
log entry corresponding to that key (as created by collect_fields_using_regexp()) into the database.
set_collected_field(string key, string log_field_name, string set_value)
This sets the collected field log_field_name, in the collected log entry specified by key,
to the value set_value.
get_collected_field(string key, string log_field_name)
This returns the value of the collected field log_field_name, in the collected log entry specified by key.
rekey_collected_entry(string F, string T)
This changes the key of the collected entry with key F so its key is T instead.
generate_report_id(string P, string A)
This creates a new report ID, which can be used to generate a report with generate_report().
P is the profile name, and A is a list of any configuration options that need to be
changed from the defaults in the report. The value of this function is the generated report ID.
generate_report(string P, string I)
This generates the report with id I, for profile P. Generation occurs
in a separate task, so this returns immediately, while report generation continues
in the background. Calls to the functions below can tap into the status of the report,
and the final generated report. The value of this function is empty.
get_progress_info(string taskid, string resultnode)
This acquires progress information for a running task with task ID taskid.
It populates the node specified by resultnode with detailed progress information.
If taskid is not a valid task or there is no progress available for that task,
resultnode will have a subnode exist with value false.
The value of this function is empty.
cached_report_exists(string P, string I)
This checks if the report from profile P with id I has been completely generated, and is now cached.
The value of this function is true if the report is cached, and false if it is not cached
(never generated or generation is in progress).
display_cached_report(string P, string I)
This displays the cached report from profile P with id I. This will fail if
the report is not cached-- call cached_report_exists() to check. The value of this function
is the complete HTML page of the report.
delete_cached_report(string P, string I)
This deletes a cached report from profile P with id I. Future calls to cached_report_exists()
will be false until this is regenerated with generate_report(). The value of this expression is empty.
verify_mysql_connection(string H, string U, string P)
This verifies that a connection can be made to the MySQL server with hostname H, username U, and password P.
get_database_info(string P, string N)
This gets various information about the database for profile P, and puts it in
node N.
build_database(string P, string R)
This builds the database for profile P. If the database build is occurring as part of
an attempt to view a report, the report ID should go in R; otherwise, R should be empty ("").
update_database(string P, string R)
This updates the database for profile P. If the database build is occurring as part of
an attempt to view a report, the report ID should go in R; otherwise, R should be empty ("").
exec(string executable, node options, bool wait)
This runs the command-line program specified by executable, from the command line.
If the executable option is an empty string, the main program executable is run
(e.g. $PRODUCT_NAME runs itself from the command line).
The options node contains the command line options; e.g., for each subnode of the options node,
the value of that option (not the name, which is ignored) is a command line option.
The wait option specified whether to wait for completion; if it is true,
exec() will not return until the command is done; if it is false, exec() will return immediately,
leaving the command running in the background. This returns the Process ID (PID) of the process if wait is false,
or zero otherwise.
get_task_info(string N)
This gets various information about currently active tasks, and puts it in node N.
cancel_task(string task_id)
This cancels an active task with ID task_id.
When this returns, the task has been cancelled.
sleep_milliseconds(int M)
This delays for M milliseconds before evaluating the next expression.
save_session_changes()
This saves any changes to the configuration hierarchy to the sessions file, so they will carry over
to future pages.
write_file(P, S)
This writes string S to a file at pathname P. If the file
does not exist, it is created; if it exists, it is overwritten.
P is a local pathname in LogAnalysisInfo, using / as pathname dividers; for instance,
to write to a file test.html in WebServerRoot in LogAnalysisInfo, use "WebServerRoot/test.html".
read_file(P)
This reads the contents of the file at pathname P. It returns the contents of the file as a string.
P is either a full pathname, or a pathname local to the $PRODUCT_NAME executable location,
using / as pathname dividers; for instance, if your LogAnalysisInfo folder is in the same
$lang_stats.directory as the $PRODUCT_NAME binary (which is typical),
then to read from a file test.html in WebServerRoot in LogAnalysisInfo,
use "LogAnalysisInfo/WebServerRoot/test.html".
send_email(string sender, string recipient, string message, string smtp_server)
This sends an email to sender from recipient, using SMTP server smtp_server.
The "message" variable is the entire contents of the message, including mail headers.
now()
This returns the current time, as the number of seconds since January 1, 1970, Coordinated Universal Time,
without including leap seconds.
localtime()
This returns the current time, as the number of seconds since January 1, 1970, in the GMT time zone.
normalize_date(string date, string format)
This computes the "normal" format (dd/mmm/yyyy) of the date in date, and returns the date in normal format.
date is in the format specified by format, which may be any
of the date formats in the list at {=docs_option_link('ldf')=}.
normalize_time(string time, string format)
This computes the "normal" format (dd/mmm/yyyy) of the time in time, and returns the time in normal format.
time is in the format specified by format, which may be any
of the time formats in the list at {=docs_option_link('ltf')=}.
date_time_to_epoc(string D)
This converts the string D, which is a date/time of the format 'dd/mmm/yyyy hh:mm:ss' (GMT)
to an epoc time (seconds since January 1, 1970). It returns the epoc time.
epoc_to_date_time(int E)
This converts the integer E, which is a date/time value in EPOC format (seconds since January 1, 1970)
to a string of the format 'dd/mmm/yyyy hh:mm:ss'. It returns string date/time.
date_time_duration(string D)
This computes the duration in minutes of the date_time unit value D, which is of the format 'dd/mmm/yyyy hh:mm:ss',
where any value may be replaced by underbars to indicate the unit size, e.g.
'01/Feb/2005 12:34:56' indicates a single second (so the value returned will be 1);
'01/Feb/2005 12:34:__' indicates a single minute (so the value returned will be 60);
'01/Feb/2005 12:__:__' indicates a single hour (so the value returned will be 3600);
'01/Feb/2005 __:__:__' indicates a single day (so the value returned will be 86400);
'__/Feb/2005 __:__:__' indicates a single month (so the value returned will be the duration of the month, in seconds);
and '__/___/2005 __:__:__' indicates a single year (so the value returned will be the duration of the year, in seconds).
The value of this format is used frequently in report filters; this function is useful for computing durations of filtered data.
clear_session_changes()
This clears any changes to the configuration hierarchy saved using save_session_changes().
I.e. this reverts to the last saved version of the configuration hierarchy saved using save_changes().
start_progress_meter_step(string O)
This starts a progress meter step with operation name O.
finish_progress_meter_step(string O)
This finishes a progress meter step with operation name O.
set_progress_meter_maximum(float M)
This sets the maximum progress meter value to M.
set_progress_meter_position(float M)
This sets the current position of the progress meter to P (out of a total
value specified by set_progress_meter_maximum()). This also causes the
progress meter to be updated if necessary; call this function regularly
during long operations to ensure that progress occurs properly.
current_log_pathname()
Returns the pathname of the log file currently being processed (for log filters).
current_log_line()
Returns the entire current line of log data being processed (for log filters).
sin(float X)
This returns the sine of X.
cos(float X)
This returns the cosine of X.
tan(float X)
This returns the tangent of X.
asin(float X)
This returns the arc sine of X.
acos(float X)
This returns the arc cosine of X.
atan(float X)
This returns the arc tangent of X.
atan2(float X, float Y)
This returns the arc tangent of X/Y, using the signs of X and Y to compute the quadrant of the result.