]> granicus.if.org Git - icinga2/blob - doc/17-language-reference.md
Add exclude/include to vmware-esx-soap-host-runtime docs
[icinga2] / doc / 17-language-reference.md
1 # Language Reference <a id="language-reference"></a>
2
3 ## Object Definition <a id="object-definition"></a>
4
5 Icinga 2 features an object-based configuration format. You can define new
6 objects using the `object` keyword:
7
8     object Host "host1.example.org" {
9       display_name = "host1"
10
11       address = "192.168.0.1"
12       address6 = "::1"
13     }
14
15 In general you need to write each statement on a new line. Expressions started
16 with `{`, `(` and `[` extend until the matching closing character and can be broken
17 up into multiple lines.
18
19 Alternatively you can write multiple statements on a single line by separating
20 them with a semicolon:
21
22     object Host "host1.example.org" {
23       display_name = "host1"
24
25       address = "192.168.0.1"; address6 = "::1"
26     }
27
28 Each object is uniquely identified by its type (`Host`) and name
29 (`host1.example.org`). Some types have composite names, e.g. the
30 `Service` type which uses the `host_name` attribute and the name
31 you specified to generate its object name.
32
33 Exclamation marks (!) are not permitted in object names.
34
35 Objects can contain a comma-separated list of property
36 declarations. Instead of commas semicolons may also be used.
37 The following data types are available for property values:
38
39 All objects have at least the following attributes:
40
41 Attribute            | Description
42 ---------------------|-----------------------------
43 name                 | The name of the object. This attribute can be modified in the object definition to override the name specified with the `object` directive.
44 type                 | The type of the object.
45
46 ## Expressions <a id="expressions"></a>
47
48 The following expressions can be used on the right-hand side of assignments.
49
50 ### Numeric Literals <a id="numeric-literals"></a>
51
52 A floating-point number.
53
54 Example:
55
56     27.3
57
58 ### Duration Literals <a id="duration-literals"></a>
59
60 Similar to floating-point numbers except for the fact that they support
61 suffixes to help with specifying time durations.
62
63 Example:
64
65     2.5m
66
67 Supported suffixes include ms (milliseconds), s (seconds), m (minutes),
68 h (hours) and d (days).
69
70 Duration literals are converted to seconds by the config parser and
71 are treated like numeric literals.
72
73 ### String Literals <a id="string-literals"></a>
74
75 A string.
76
77 Example:
78
79     "Hello World!"
80
81 #### String Literals Escape Sequences <a id="string-literals-escape-sequences"></a>
82
83 Certain characters need to be escaped. The following escape sequences
84 are supported:
85
86 Character                 | Escape sequence
87 --------------------------|------------------------------------
88 "                         | \\"
89 \\                        | \\\\
90 &lt;TAB&gt;               | \\t
91 &lt;CARRIAGE-RETURN&gt;   | \\r
92 &lt;LINE-FEED&gt;         | \\n
93 &lt;BEL&gt;               | \\b
94 &lt;FORM-FEED&gt;         | \\f
95
96 In addition to these pre-defined escape sequences you can specify
97 arbitrary ASCII characters using the backslash character (\\) followed
98 by an ASCII character in octal encoding.
99
100 ### Multi-line String Literals <a id="multiline-string-literals"></a>
101
102 Strings spanning multiple lines can be specified by enclosing them in
103 {{{ and }}}.
104
105 Example:
106
107     {{{This
108     is
109     a multi-line
110     string.}}}
111
112 Unlike in ordinary strings special characters do not have to be escaped
113 in multi-line string literals.
114
115 ### Boolean Literals <a id="boolean-literals"></a>
116
117 The keywords `true` and `false` are used to denote truth values.
118
119 ### Null Value <a id="null-value"></a>
120
121 The `null` keyword can be used to specify an empty value.
122
123 ### Dictionary <a id="dictionary"></a>
124
125 An unordered list of key-value pairs. Keys must be unique and are
126 compared in a case-sensitive manner.
127
128 Individual key-value pairs must either be comma-separated or on separate lines.
129 The comma after the last key-value pair is optional.
130
131 Example:
132
133     {
134       address = "192.168.0.1"
135       port = 443
136     }
137
138 Identifiers may not contain certain characters (e.g. space) or start
139 with certain characters (e.g. digits). If you want to use a dictionary
140 key that is not a valid identifier, you can enclose the key in double
141 quotes.
142
143 ### Array <a id="array"></a>
144
145 An ordered list of values.
146
147 Individual array elements must be comma-separated.
148 The comma after the last element is optional.
149
150 Example:
151
152     [ "hello", 42 ]
153
154 An array may simultaneously contain values of different types, such as
155 strings and numbers.
156
157 ### Operators <a id="expression-operators"></a>
158
159 The following operators are supported in expressions. The operators are sorted by descending precedence.
160
161 Operator | Precedence | Examples (Result)                             | Description
162 ---------|------------|-----------------------------------------------|--------------------------------
163 ()       | 1          | (3 + 3) * 5                                   | Groups sub-expressions
164 ()       | 1          | Math.random()                                 | Calls a function
165 []       | 1          | a[3]                                          | Array subscript
166 .        | 1          | a.b                                           | Element access
167 !        | 2          | !"Hello" (false), !false (true)               | Logical negation of the operand
168 ~        | 2          | ~true (false)                                 | Bitwise negation of the operand
169 +        | 2          | +3                                            | Unary plus
170 -        | 2          | -3                                            | Unary minus
171 *        | 3          | 5m * 10 (3000)                                | Multiplies two numbers
172 /        | 3          | 5m / 5 (60)                                   | Divides two numbers
173 %        | 3          | 17 % 12 (5)                                   | Remainder after division
174 +        | 4          | 1 + 3 (4), "hello " + "world" ("hello world") | Adds two numbers; concatenates strings
175 -        | 4          | 3 - 1 (2)                                     | Subtracts two numbers
176 <<       | 5          | 4 << 8 (1024)                                 | Left shift
177 >>       | 5          | 1024 >> 4 (64)                                | Right shift
178 <        | 6         | 3 < 5 (true)                                  | Less than
179 >        | 6         | 3 > 5 (false)                                 | Greater than
180 <=       | 6         | 3 <= 3 (true)                                 | Less than or equal
181 >=       | 6         | 3 >= 3 (true)                                 | Greater than or equal
182 in       | 7          | "foo" in [ "foo", "bar" ] (true)              | Element contained in array
183 !in      | 7          | "foo" !in [ "bar", "baz" ] (true)             | Element not contained in array
184 ==       | 8         | "hello" == "hello" (true), 3 == 5 (false)     | Equal to
185 !=       | 8         | "hello" != "world" (true), 3 != 3 (false)     | Not equal to
186 &        | 9          | 7 & 3 (3)                                     | Binary AND
187 ^        | 10          | 17 ^ 12 (29)                                  | Bitwise XOR
188 &#124;   | 11          | 2 &#124; 3 (3)                                | Binary OR
189 &&       | 13         | true && false (false), 3 && 7 (7), 0 && 7 (0) | Logical AND
190 &#124;&#124; | 14     | true &#124;&#124; false (true), 0 &#124;&#124; 7 (7)| Logical OR
191 =        | 12         | a = 3                                         | Assignment
192 =>       | 15         | x => x * x (function with arg x)              | Lambda, for loop
193
194 ### Function Calls <a id="function-calls"></a>
195
196 Functions can be called using the `()` operator:
197
198     const MyGroups = [ "test1", "test" ]
199
200     {
201       check_interval = len(MyGroups) * 1m
202     }
203
204 A list of available functions is available in the [Library Reference](18-library-reference.md#library-reference) chapter.
205
206 ## Assignments <a id="dictionary-operators"></a>
207
208 In addition to the `=` operator shown above a number of other operators
209 to manipulate attributes are supported. Here's a list of all
210 available operators:
211
212 ### Operator = <a id="operator-assignment"></a>
213
214 Sets an attribute to the specified value.
215
216 Example:
217
218     {
219       a = 5
220       a = 7
221     }
222
223 In this example `a` has the value `7` after both instructions are executed.
224
225 ### Operator += <a id="operator-additive-assignment"></a>
226
227 The += operator is a shortcut. The following expression:
228
229     {
230       a = [ "hello" ]
231       a += [ "world" ]
232     }
233
234 is equivalent to:
235
236     {
237       a = [ "hello" ]
238       a = a + [ "world" ]
239     }
240
241 ### Operator -= <a id="operator-substractive-assignment"></a>
242
243 The -= operator is a shortcut. The following expression:
244
245     {
246       a = 10
247       a -= 5
248     }
249
250 is equivalent to:
251
252     {
253       a = 10
254       a = a - 5
255     }
256
257 ### Operator \*= <a id="operator-multiply-assignment"></a>
258
259 The *= operator is a shortcut. The following expression:
260
261     {
262       a = 60
263       a *= 5
264     }
265
266 is equivalent to:
267
268     {
269       a = 60
270       a = a * 5
271     }
272
273 ### Operator /= <a id="operator-dividing-assignment"></a>
274
275 The /= operator is a shortcut. The following expression:
276
277     {
278       a = 300
279       a /= 5
280     }
281
282 is equivalent to:
283
284     {
285       a = 300
286       a = a / 5
287     }
288
289 ## Indexer <a id="indexer"></a>
290
291 The indexer syntax provides a convenient way to set dictionary elements.
292
293 Example:
294
295     {
296       hello.key = "world"
297     }
298
299 Example (alternative syntax):
300
301     {
302       hello["key"] = "world"
303     }
304
305 This is equivalent to writing:
306
307     {
308       hello += {
309         key = "world"
310       }
311     }
312
313 If the `hello` attribute does not already have a value, it is automatically initialized to an empty dictionary.
314
315 ## Template Imports <a id="template-imports"></a>
316
317 Objects can import attributes from other objects.
318
319 Example:
320
321     template Host "default-host" {
322       vars.colour = "red"
323     }
324
325     template Host "test-host" {
326       import "default-host"
327
328       vars.colour = "blue"
329     }
330
331     object Host "localhost" {
332       import "test-host"
333
334       address = "127.0.0.1"
335       address6 = "::1"
336     }
337
338 The `default-host` and `test-host` objects are marked as templates
339 using the `template` keyword. Unlike ordinary objects templates are not
340 instantiated at run-time. Parent objects do not necessarily have to be
341 templates, however in general they are.
342
343 The `vars` dictionary for the `localhost` object contains all three
344 custom attributes and the custom attribute `colour` has the value `"blue"`.
345
346 Parent objects are resolved in the order they're specified using the
347 `import` keyword.
348
349 Default templates which are automatically imported into all object definitions
350 can be specified using the `default` keyword:
351
352     template CheckCommand "plugin-check-command" default {
353       // ...
354     }
355
356 Default templates are imported before any other user-specified statement in an
357 object definition is evaluated.
358
359 If there are multiple default templates the order in which they are imported
360 is unspecified.
361
362 ## Constants <a id="constants"></a>
363
364 Global constants can be set using the `const` keyword:
365
366     const VarName = "some value"
367
368 Once defined a constant can be accessed from any file. Constants cannot be changed
369 once they are set.
370
371 > **Tip**
372 >
373 > Best practice is to manage constants in the [constants.conf](04-configuring-icinga-2.md#constants-conf) file.
374
375 ### Icinga 2 Specific Constants <a id="icinga-constants"></a>
376
377 Icinga 2 provides a number of special global constants. Some of them can be overridden using the `--define` command line parameter:
378
379 Variable            |Description
380 --------------------|-------------------
381 PrefixDir           |**Read-only.** Contains the installation prefix that was specified with cmake -DCMAKE_INSTALL_PREFIX. Defaults to "/usr/local".
382 SysconfDir          |**Read-only.** Contains the path of the sysconf directory. Defaults to PrefixDir + "/etc".
383 ZonesDir            |**Read-only.** Contains the path of the zones.d directory. Defaults to SysconfDir + "/zones.d".
384 LocalStateDir       |**Read-only.** Contains the path of the local state directory. Defaults to PrefixDir + "/var".
385 RunDir              |**Read-only.** Contains the path of the run directory. Defaults to LocalStateDir + "/run".
386 PkgDataDir          |**Read-only.** Contains the path of the package data directory. Defaults to PrefixDir + "/share/icinga2".
387 StatePath           |**Read-write.** Contains the path of the Icinga 2 state file. Defaults to LocalStateDir + "/lib/icinga2/icinga2.state".
388 ObjectsPath         |**Read-write.** Contains the path of the Icinga 2 objects file. Defaults to LocalStateDir + "/cache/icinga2/icinga2.debug".
389 PidPath             |**Read-write.** Contains the path of the Icinga 2 PID file. Defaults to RunDir + "/icinga2/icinga2.pid".
390 Vars                |**Read-write.** Contains a dictionary with global custom attributes. Not set by default.
391 NodeName            |**Read-write.** Contains the cluster node name. Set to the local hostname by default.
392 RunAsUser           |**Read-write.** Defines the user the Icinga 2 daemon is running as. Set in the Icinga 2 sysconfig.
393 RunAsGroup          |**Read-write.** Defines the group the Icinga 2 daemon is running as. Set in the Icinga 2 sysconfig.
394 PlatformName        |**Read-only.** The name of the operating system, e.g. "Ubuntu".
395 PlatformVersion     |**Read-only.** The version of the operating system, e.g. "14.04.3 LTS".
396 PlatformKernel      |**Read-only.** The name of the operating system kernel, e.g. "Linux".
397 PlatformKernelVersion|**Read-only.** The version of the operating system kernel, e.g. "3.13.0-63-generic".
398 BuildCompilerName   |**Read-only.** The name of the compiler Icinga was built with, e.g. "Clang".
399 BuildCompilerVersion|**Read-only.** The version of the compiler Icinga was built with, e.g. "7.3.0.7030031".
400 BuildHostName       |**Read-only.** The name of the host Icinga was built on, e.g. "acheron".
401 ApplicationVersion  |**Read-only.** The application version, e.g. "2.9.0".
402 MaxConcurrentChecks |**Read-write**. The number of max checks run simultaneously. Defaults to 512.
403 Environment         |**Read-write**. The name of the Icinga environment. Included in the SNI host name when making outbound connections. Defaults to "production".
404
405
406 Advanced runtime constants. Please only use them if advised by support or developers.
407
408 Variable                   | Description
409 ---------------------------|-------------------
410 EventEngine                |**Read-write.** The name of the socket event engine, can be `poll` or `epoll`. The epoll interface is only supported on Linux.
411 AttachDebugger             |**Read-write.** Whether to attach a debugger when Icinga 2 crashes. Defaults to `false`.
412 ICINGA2\_RLIMIT\_FILES     |**Read-write.** Defines the resource limit for RLIMIT_NOFILE that should be set at start-up. Value cannot be set lower than the default `16 * 1024`. 0 disables the setting. Set in Icinga 2 sysconfig.
413 ICINGA2\_RLIMIT\_PROCESSES |**Read-write.** Defines the resource limit for RLIMIT_NPROC that should be set at start-up. Value cannot be set lower than the default `16 * 1024`. 0 disables the setting. Set in Icinga 2 sysconfig.
414 ICINGA2\_RLIMIT\_STACK     |**Read-write.** Defines the resource limit for RLIMIT_STACK that should be set at start-up. Value cannot be set lower than the default `256 * 1024`. 0 disables the setting. Set in Icinga 2 sysconfig.
415
416 ## Apply <a id="apply"></a>
417
418 The `apply` keyword can be used to create new objects which are associated with
419 another group of objects.
420
421     apply Service "ping" to Host {
422       import "generic-service"
423
424       check_command = "ping4"
425
426       assign where host.name == "localhost"
427     }
428
429 In this example the `assign where` condition is a boolean expression which is
430 evaluated for all objects of type `Host` and a new service with name "ping"
431 is created for each matching host. [Expression operators](17-language-reference.md#expression-operators)
432 may be used in `assign where` conditions.
433
434 The `to` keyword and the target type may be omitted if there is only one target
435 type, e.g. for the `Service` type.
436
437 Depending on the object type used in the `apply` expression additional local
438 variables may be available for use in the `where` condition:
439
440 Source Type       | Target Type | Variables
441 ------------------|-------------|--------------
442 Service           | Host        | host
443 Dependency        | Host        | host
444 Dependency        | Service     | host, service
445 Notification      | Host        | host
446 Notification      | Service     | host, service
447 ScheduledDowntime | Host        | host
448 ScheduledDowntime | Service     | host, service
449
450 Any valid config attribute can be accessed using the `host` and `service`
451 variables. For example, `host.address` would return the value of the host's
452 "address" attribute -- or null if that attribute isn't set.
453
454 More usage examples are documented in the [monitoring basics](03-monitoring-basics.md#using-apply-expressions)
455 chapter.
456
457 ## Apply For <a id="apply-for"></a>
458
459 [Apply](17-language-reference.md#apply) rules can be extended with the
460 [for loop](17-language-reference.md#for-loops) keyword.
461
462     apply Service "prefix-" for (key => value in host.vars.dictionary) to Host {
463       import "generic-service"
464
465       check_command = "ping4"
466       vars.host_value = value
467     }
468
469
470 Any valid config attribute can be accessed using the `host` and `service`
471 variables. The attribute must be of the Array or Dictionary type. In this example
472 `host.vars.dictionary` is of the Dictionary type which needs a key-value-pair
473 as iterator.
474
475 In this example all generated service object names consist of `prefix-` and
476 the value of the `key` iterator. The prefix string can be omitted if not required.
477
478 The `key` and `value` variables can be used for object attribute assignment, e.g. for
479 setting the `check_command` attribute or custom attributes as command parameters.
480
481 `apply for` rules are first evaluated against all objects matching the `for loop` list
482 and afterwards the `assign where` and `ignore where` conditions are evaluated.
483
484 It is not necessary to check attributes referenced in the `for loop` expression
485 for their existance using an additional `assign where` condition.
486
487 More usage examples are documented in the [monitoring basics](03-monitoring-basics.md#using-apply-for)
488 chapter.
489
490 ## Group Assign <a id="group-assign"></a>
491
492 Group objects can be assigned to specific member objects using the `assign where`
493 and `ignore where` conditions.
494
495     object HostGroup "linux-servers" {
496       display_name = "Linux Servers"
497
498       assign where host.vars.os == "Linux"
499     }
500
501 In this example the `assign where` condition is a boolean expression which is evaluated
502 for all objects of the type `Host`. Each matching host is added as member to the host group
503 with the name "linux-servers". Membership exclusion can be controlled using the `ignore where`
504 condition. [Expression operators](17-language-reference.md#expression-operators) may be used in `assign where` and
505 `ignore where` conditions.
506
507 Source Type       | Variables
508 ------------------|--------------
509 HostGroup         | host
510 ServiceGroup      | host, service
511 UserGroup         | user
512
513
514 ## Boolean Values <a id="boolean-values"></a>
515
516 The `assign where`, `ignore where`, `if` and `while`  statements, the `!` operator as
517 well as the `bool()` function convert their arguments to a boolean value based on the
518 following rules:
519
520 Description          | Example Value     | Boolean Value
521 ---------------------|-------------------|--------------
522 Empty value          | null              | false
523 Zero                 | 0                 | false
524 Non-zero integer     | -23945            | true
525 Empty string         | ""                | false
526 Non-empty string     | "Hello"           | true
527 Empty array          | []                | false
528 Non-empty array      | [ "Hello" ]       | true
529 Empty dictionary     | {}                | false
530 Non-empty dictionary | { key = "value" } | true
531
532 For a list of supported expression operators for `assign where` and `ignore where`
533 statements, see [expression operators](17-language-reference.md#expression-operators).
534
535 ## Comments <a id="comments"></a>
536
537 The Icinga 2 configuration format supports C/C++-style and shell-style comments.
538
539 Example:
540
541     /*
542      This is a comment.
543      */
544     object Host "localhost" {
545       check_interval = 30 // this is also a comment.
546       retry_interval = 15 # yet another comment
547     }
548
549 ## Includes <a id="includes"></a>
550
551 Other configuration files can be included using the `include` directive.
552 Paths must be relative to the configuration file that contains the
553 `include` directive.
554
555 Example:
556
557     include "some/other/file.conf"
558     include "conf.d/*.conf"
559
560 Wildcard includes are not recursive.
561
562 Icinga also supports include search paths similar to how they work in a
563 C/C++ compiler:
564
565     include <itl>
566
567 Note the use of angle brackets instead of double quotes. This causes the
568 config compiler to search the include search paths for the specified
569 file. By default $PREFIX/share/icinga2/include is included in the list of search
570 paths. Additional include search paths can be added using
571 [command-line options](11-cli-commands.md#config-include-path).
572
573 Wildcards are not permitted when using angle brackets.
574
575 ## Recursive Includes <a id="recursive-includes"></a>
576
577 The `include_recursive` directive can be used to recursively include all
578 files in a directory which match a certain pattern.
579
580 Example:
581
582     include_recursive "conf.d", "*.conf"
583     include_recursive "templates"
584
585 The first parameter specifies the directory from which files should be
586 recursively included.
587
588 The file names need to match the pattern given in the second parameter.
589 When no pattern is specified the default pattern "*.conf" is used.
590
591 ## Zone Includes <a id="zone-includes"></a>
592
593 The `include_zones` recursively includes all subdirectories for the
594 given path.
595
596 In addition to that it sets the `zone` attribute for all objects created
597 in these subdirectories to the name of the subdirectory.
598
599 Example:
600
601     include_zones "etc", "zones.d", "*.conf"
602     include_zones "puppet", "puppet-zones"
603
604 The first parameter specifies a tag name for this directive. Each `include_zones`
605 invocation should use a unique tag name. When copying the zones' configuration
606 files Icinga uses the tag name as the name for the destination directory in
607 `/var/lib/icinga2/api/config`.
608
609 The second parameter specifies the directory which contains the subdirectories.
610
611 The file names need to match the pattern given in the third parameter.
612 When no pattern is specified the default pattern "*.conf" is used.
613
614 ## Library directive <a id="library"></a>
615
616 The `library` directive was used to manually load additional
617 libraries. Starting with version 2.9 it is no longer necessary to explicitly load
618 libraries and this directive has no effect.
619
620 ## Functions <a id="functions"></a>
621
622 Functions can be defined using the `function` keyword.
623
624 Example:
625
626     function multiply(a, b) {
627       return a * b
628     }
629
630 When encountering the `return` keyword further execution of the function is terminated and
631 the specified value is supplied to the caller of the function:
632
633     log(multiply(3, 5))
634
635 In this example the `multiply` function we declared earlier is invoked with two arguments (3 and 5).
636 The function computes the product of those arguments and makes the result available to the
637 function's caller.
638
639 When no value is supplied for the `return` statement the function returns `null`.
640
641 Functions which do not have a `return` statement have their return value set to the value of the
642 last expression which was performed by the function. For example, we could have also written our
643 `multiply` function like this:
644
645     function multiply(a, b) {
646       a * b
647     }
648
649 Anonymous functions can be created by omitting the name in the function definition. The
650 resulting function object can be used like any other value:
651
652     var fn = function() { 3 }
653
654     fn() /* Returns 3 */
655
656 ## Lambda Expressions <a id="lambdas"></a>
657
658 Functions can also be declared using the alternative lambda syntax.
659
660 Example:
661
662     f = (x) => x * x
663
664 Multiple statements can be used by putting the function body into braces:
665
666     f = (x) => {
667       log("Lambda called")
668       x * x
669     }
670
671 Just like with ordinary functions the return value is the value of the last statement.
672
673 For lambdas which take exactly one argument the braces around the arguments can be omitted:
674
675     f = x => x * x
676
677 ## Abbreviated Lambda Syntax <a id="nullary-lambdas"></a>
678
679 Lambdas which take no arguments can also be written using the abbreviated lambda syntax.
680
681 Example:
682
683     f = {{ 3 }}
684
685 This creates a new function which returns the value 3.
686
687 ## Variable Scopes <a id="variable-scopes"></a>
688
689 When setting a variable Icinga checks the following scopes in this order whether the variable
690 already exists there:
691
692 * Local Scope
693 * `this` Scope
694 * Global Scope
695
696 The local scope contains variables which only exist during the invocation of the current function,
697 object or apply statement. Local variables can be declared using the `var` keyword:
698
699     function multiply(a, b) {
700       var temp = a * b
701       return temp
702     }
703
704 Each time the `multiply` function is invoked a new `temp` variable is used which is in no way
705 related to previous invocations of the function.
706
707 When setting a variable which has not previously been declared as local using the `var` keyword
708 the `this` scope is used.
709
710 The `this` scope refers to the current object which the function or object/apply statement
711 operates on.
712
713     object Host "localhost" {
714       check_interval = 5m
715     }
716
717 In this example the `this` scope refers to the "localhost" object. The `check_interval` attribute
718 is set for this particular host.
719
720 You can explicitly access the `this` scope using the `this` keyword:
721
722     object Host "localhost" {
723       var check_interval = 5m
724   
725       /* This explicitly specifies that the attribute should be set
726        * for the host, if we had omitted `this.` the (poorly named)
727        * local variable `check_interval` would have been modified instead.
728        */
729       this.check_interval = 1m 
730   }
731
732 Similarly the keywords `locals` and `globals` are available to access the local and global scope.
733
734 Functions also have a `this` scope. However unlike for object/apply statements the `this` scope for
735 a function is set to whichever object was used to invoke the function. Here's an example:
736
737      hm = {
738        h_word = null
739  
740        function init(word) {
741          h_word = word
742        }
743      }
744
745      /* Let's invoke the init() function */
746      hm.init("hello")
747
748 We're using `hm.init` to invoke the function which causes the value of `hm` to become the `this`
749 scope for this function call.
750
751 ## Closures <a id="closures"></a>
752
753 By default `function`s, `object`s and `apply` rules do not have access to variables declared
754 outside of their scope (except for global variables).
755
756 In order to access variables which are defined in the outer scope the `use` keyword can be used:
757
758     function MakeHelloFunction(name) {
759       return function() use(name) {
760         log("Hello, " + name)
761       }
762     }
763
764 In this case a new variable `name` is created inside the inner function's scope which has the
765 value of the `name` function argument.
766
767 Alternatively a different value for the inner variable can be specified:
768
769     function MakeHelloFunction(name) {
770       return function() use (greeting = "Hello, " + name) {
771         log(greeting)
772       }
773     }
774
775 ## Conditional Statements <a id="conditional-statements"></a>
776
777 Sometimes it can be desirable to only evaluate statements when certain conditions are met. The if/else
778 construct can be used to accomplish this.
779
780 Example:
781
782     a = 3
783
784     if (a < 5) {
785       a *= 7
786     } else if (a > 10) {
787       a *= 5
788     } else {
789       a *= 2
790     }
791
792 An if/else construct can also be used in place of any other value. The value of an if/else statement
793 is the value of the last statement which was evaluated for the branch which was taken:
794
795     a = if (true) {
796       log("Taking the 'true' branch")
797       7 * 3
798     } else {
799       log("Taking the 'false' branch")
800       9
801     }
802
803 This example prints the log message "Taking the 'true' branch" and the `a` variable is set to 21 (7 * 3).
804
805 The value of an if/else construct is null if the condition evaluates to false and no else branch is given.
806
807 ## While Loops <a id="while-loops"></a>
808
809 The `while` statement checks a condition and executes the loop body when the condition evaluates to `true`.
810 This is repeated until the condition is no longer true.
811
812 Example:
813
814     var num = 5
815
816     while (num > 5) {
817         log("Test")
818         num -= 1
819     }
820
821 The `continue` and `break` keywords can be used to control how the loop is executed: The `continue` keyword
822 skips over the remaining expressions for the loop body and begins the next loop evaluation. The `break` keyword
823 breaks out of the loop.
824
825 ## For Loops <a id="for-loops"></a>
826
827 The `for` statement can be used to iterate over arrays and dictionaries.
828
829 Example:
830
831     var list = [ "a", "b", "c" ]
832
833     for (var item in list) {
834       log("Item: " + item)
835     }
836
837 The loop body is evaluated once for each item in the array. The variable `item` is declared as a local
838 variable just as if the `var` keyword had been used.
839
840 Iterating over dictionaries can be accomplished in a similar manner:
841
842     var dict = { a = 3, b = 7 }
843
844     for (var key => var value in dict) {
845       log("Key: " + key + ", Value: " + value)
846     }
847
848 The `continue` and `break` keywords can be used to control how the loop is executed: The `continue` keyword
849 skips over the remaining expressions for the loop body and begins the next loop evaluation. The `break` keyword
850 breaks out of the loop.
851
852 The `var` keyword is optional when declaring variables in the loop's header. Variables declared without the `var`
853 keyword are nonetheless local to the function.
854
855 ## Constructors <a id="constructor"></a>
856
857 In order to create a new value of a specific type constructor calls may be used.
858
859 Example:
860
861     var pd = PerfdataValue()
862     pd.label = "test"
863     pd.value = 10
864
865 You can also try to convert an existing value to another type by specifying it as an argument for the constructor call.
866
867 Example:
868
869     var s = String(3) /* Sets s to "3". */
870
871 ## Throwing Exceptions <a id="throw"></a>
872
873 Built-in commands may throw exceptions to signal errors such as invalid arguments. User scripts can throw exceptions
874 using the `throw` keyword.
875
876 Example:
877
878     throw "An error occurred."
879
880 ## Handling Exceptions <a id="try-except"></a>
881
882 Exceptions can be handled using the `try` and `except` keywords. When an exception occurs while executing code in the
883 `try` clause no further statements in the `try` clause are evaluated and the `except` clause is executed instead.
884
885 Example:
886
887     try {
888         throw "Test"
889
890         log("This statement won't get executed.")
891     } except {
892         log("An error occurred in the try clause.")
893     }
894
895 ## Breakpoints <a id="breakpoints"></a>
896
897 The `debugger` keyword can be used to insert a breakpoint. It may be used at any place where an assignment would also be a valid expression.
898
899 By default breakpoints have no effect unless Icinga is started with the `--script-debugger` command-line option. When the script debugger is enabled Icinga stops execution of the script when it encounters a breakpoint and spawns a console which lets the user inspect the current state of the execution environment.
900
901 ## Types <a id="types"></a>
902
903 All values have a static type. The `typeof` function can be used to determine the type of a value:
904
905     typeof(3) /* Returns an object which represents the type for numbers */
906
907 The following built-in types are available:
908
909 Type       | Examples          | Description
910 -----------|-------------------|------------------------
911 Number     | 3.7               | A numerical value.
912 Boolean    | true, false       | A boolean value.
913 String     | "hello"           | A string.
914 Array      | [ "a", "b" ]      | An array.
915 Dictionary | { a = 3 }         | A dictionary.
916
917 Depending on which libraries are loaded additional types may become available. The `icinga`
918 library implements a whole bunch of other [object types](09-object-types.md#object-types),
919 e.g. Host, Service, CheckCommand, etc.
920
921 Each type has an associated type object which describes the type's semantics. These
922 type objects are made available using global variables which match the type's name:
923
924     /* This logs 'true' */
925     log(typeof(3) == Number)
926
927 The type object's `prototype` property can be used to find out which methods a certain type
928 supports:
929
930     /* This returns: ["contains","find","len","lower","replace","reverse","split","substr","to_string","trim","upper"] */
931     keys(String.prototype)
932
933 Additional documentation on type methods is available in the
934 [library reference](18-library-reference.md#library-reference).
935
936 ## Location Information <a id="location-information"></a>
937
938 The location of the currently executing script can be obtained using the
939 `current_filename` and `current_line` keywords.
940
941 Example:
942
943     log("Hello from '" + current_filename + "' in line " + current_line)
944
945 ## Reserved Keywords <a id="reserved-keywords"></a>
946
947 These keywords are reserved and must not be used as constants or custom attributes.
948
949     object
950     template
951     include
952     include_recursive
953     include_zones
954     library
955     null
956     true
957     false
958     const
959     var
960     this
961     globals
962     locals
963     use
964     default
965     ignore_on_error
966     current_filename
967     current_line
968     apply
969     to
970     where
971     import
972     assign
973     ignore
974     function
975     return
976     break
977     continue
978     for
979     if
980     else
981     while
982     throw
983     try
984     except
985     in
986
987 You can escape reserved keywords using the `@` character. The following example
988 tries to set `vars.include` which references a reserved keyword and generates
989 an error:
990
991     [2014-09-15 17:24:00 +0200] critical/config: Location:
992     /etc/icinga2/conf.d/hosts/localhost.conf(13):   vars.sla = "24x7"
993     /etc/icinga2/conf.d/hosts/localhost.conf(14):
994     /etc/icinga2/conf.d/hosts/localhost.conf(15):   vars.include = "some cmdb export field"
995                                                          ^^^^^^^
996     /etc/icinga2/conf.d/hosts/localhost.conf(16): }
997     /etc/icinga2/conf.d/hosts/localhost.conf(17):
998
999     Config error: in /etc/icinga2/conf.d/hosts/localhost.conf: 15:8-15:14: syntax error, unexpected include (T_INCLUDE), expecting T_IDENTIFIER
1000     [2014-09-15 17:24:00 +0200] critical/config: 1 errors, 0 warnings.
1001
1002 You can escape the `include` keyword by prefixing it with an additional `@` character:
1003
1004     object Host "localhost" {
1005       import "generic-host"
1006
1007       address = "127.0.0.1"
1008       address6 = "::1"
1009
1010       vars.os = "Linux"
1011       vars.sla = "24x7"
1012
1013       vars.@include = "some cmdb export field"
1014     }
1015