File: epnplugins.html

package info (click to toggle)
icinga 1.14.2%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 49,264 kB
  • sloc: ansic: 108,564; sql: 9,656; sh: 4,945; perl: 3,439; makefile: 1,213; php: 581; xml: 104
file content (309 lines) | stat: -rw-r--r-- 13,529 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>11.2. Developing Plugins For Use With Embedded Perl</title>
<link rel="stylesheet" href="../stylesheets/icinga-docs.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.1">
<meta name="keywords" content="Supervision, Icinga, Nagios, Linux">
<link rel="home" href="index.html" title="Icinga Version 1.14 Documentation">
<link rel="up" href="ch11.html" title="Chapter 11. Development">
<link rel="prev" href="pluginapi.html" title="11.1. Icinga Plugin API">
<link rel="next" href="icinga-api.html" title="11.3. No Icinga API to install anymore">
<script src="../js/jquery-min.js" type="text/javascript"></script><script src="../js/icinga-docs.js" type="text/javascript"></script>
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<CENTER><IMG src="../images/logofullsize.png" border="0" alt="Icinga" title="Icinga"></CENTER>
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr><th colspan="3" align="center">11.2. Developing Plugins For Use With Embedded Perl</th></tr>
<tr>
<td width="20%" align="left">
<a accesskey="p" href="pluginapi.html">Prev</a> </td>
<th width="60%" align="center">Chapter 11. Development</th>
<td width="20%" align="right"> <a accesskey="n" href="icinga-api.html">Next</a>
</td>
</tr>
</table>
<hr>
</div>
<div class="section" title="11.2. Developing Plugins For Use With Embedded Perl">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="epnplugins"></a>11.2. <a name="epn_plugins"></a>Developing Plugins For Use With Embedded Perl</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section">11.2.1. <a href="epnplugins.html#introduction">Introduction</a></span></dt>
<dt><span class="section">11.2.2. <a href="epnplugins.html#targetaudience">Target Audience</a></span></dt>
<dt><span class="section">11.2.3. <a href="epnplugins.html#todo">Things you should do when developing a Perl Plugin (ePN or not)</a></span></dt>
<dt><span class="section">11.2.4. <a href="epnplugins.html#nottodo">Things you must do to develop a Perl plugin for ePN</a></span></dt>
</dl></div>
  

  <div class="section" title="11.2.1. Introduction">
<div class="titlepage"><div><div><h3 class="title">
<a name="introduction"></a>11.2.1. Introduction</h3></div></div></div>
	  

  <p>Stanley Hopcroft has worked with the embedded Perl interpreter quite a bit and has commented on the advantages/disadvanges
  of using it. He has also given several helpful hints on creating Perl plugins that work properly with the embedded interpreter.
  The majority of this documentation comes from his comments.</p>

  <p>It should be noted that "ePN", as used in this documentation, refers to embedded Perl Nagios, or if you prefer,
  Icinga compiled with an embedded Perl interpreter.</p>

  </div>

  <div class="section" title="11.2.2. Target Audience">
<div class="titlepage"><div><div><h3 class="title">
<a name="targetaudience"></a>11.2.2. Target Audience</h3></div></div></div>
	  

  <div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
      <p>Average Perl developers; those with an appreciation of the languages powerful features without knowledge of internals
      or an in depth knowledge of those features.</p>
    </li>
<li class="listitem">
      <p>Those with a utilitarian appreciation rather than a great depth of understanding.</p>
    </li>
<li class="listitem">
      <p>If you are happy with Perl objects, name management, data structures, and the debugger, that's probably
      sufficient.</p>
    </li>
</ul></div>

  </div>

  <div class="section" title="11.2.3. Things you should do when developing a Perl Plugin (ePN or not)">
<div class="titlepage"><div><div><h3 class="title">
<a name="todo"></a>11.2.3. Things you should do when developing a Perl Plugin (ePN or not)</h3></div></div></div>
	  

  <div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
      <p>Always always generate some output</p>
    </li>
<li class="listitem">
      <p>Use 'use utils' and import the stuff it exports ($TIMEOUT %ERRORS &amp;print_revision &amp;support)</p>
    </li>
<li class="listitem">
      <p>Have a look at how the standard Perl plugins do their stuff e.g.</p>

      <div class="itemizedlist"><ul class="itemizedlist" type="circle">
<li class="listitem">
          <p>Always exit with $ERRORS{CRITICAL}, $ERRORS{OK}, etc.</p>
        </li>
<li class="listitem">
          <p>Use getopt to read command line arguments</p>
        </li>
<li class="listitem">
          <p>Manage timeouts</p>
        </li>
<li class="listitem">
          <p>Call print_usage (supplied by you) when there are no command line arguments</p>
        </li>
<li class="listitem">
          <p>Use standard switch names (e.g. H 'host', V 'version')</p>
        </li>
</ul></div>
    </li>
</ul></div>

  </div>

  <div class="section" title="11.2.4. Things you must do to develop a Perl plugin for ePN">
<div class="titlepage"><div><div><h3 class="title">
<a name="nottodo"></a>11.2.4. Things you must do to develop a Perl plugin for ePN</h3></div></div></div>
	  

  <div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">
      <p>&lt;DATA&gt; can not be used; use here documents instead e.g.</p>

      <pre class="screen">my $data = &lt;&lt;DATA;
portmapper 100000
portmap 100000
sunrpc 100000
rpcbind 100000
rstatd 100001
rstat 100001
rup 100001
..
DATA

%prognum = map { my($a, $b) = split; ($a, $b) } split(/\n/, $data) ;</pre>
    </li>
<li class="listitem">
      <p>BEGIN blocks will not work as you expect. May be best to avoid.</p>
    </li>
<li class="listitem">
      <p>Ensure that it is squeaky clean at compile time i.e.</p>

      <div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
          <p>use strict</p>
        </li>
<li class="listitem">
          <p>use perl -w (other switches [T notably] may not help)</p>
        </li>
<li class="listitem">
          <p>use perl -c</p>
        </li>
</ul></div>
    </li>
<li class="listitem">
      <p>Avoid lexical variables (my) with global scope as a means of passing __variable__ data into subroutines. In fact this
      is __fatal__ if the subroutine is called by the plugin more than once when the check is run. Such subroutines act as
      'closures' that lock the global lexicals first value into subsequent calls of the subroutine. If however, your global is
      read-only (a complicated structure for example) this is not a problem. What Bekman <a class="link" href="http://perl.apache.org/docs/1.0/guide/" target="_top">recommends you do instead</a>, is any of the following:</p>

      <div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
          <p>make the subroutine anonymous and call it via a code ref e.g.</p>

          <pre class="screen">turn this                     into  

my $x = 1 ;                   my $x = 1 ;
sub a { .. Process $x ... }   $a_cr = sub { ... Process $x ... } ;
.                             .
.                             .
a ;                           &amp;$a_cr ;
$x = 2                        $x = 2 ;
a ;                           &amp;$a_cr ;

# anon closures __always__ rebind the current lexical value</pre>
        </li>
<li class="listitem">
          <p>put the global lexical and the subroutine using it in their own package (as an object or a module)</p>
        </li>
<li class="listitem">
          <p>pass info to subs as references or aliases (\$lex_var or $_[n])</p>
        </li>
<li class="listitem">
          <p>replace lexicals with package globals and exclude them from 'use strict' objections with 'use vars qw(global1
          global2 ..)'</p>
        </li>
</ul></div>
    </li>
<li class="listitem">
      <p>Be aware of where you can get more information.</p>

      <p>Useful information can be had from the usual suspects (the O'Reilly books, plus Damien Conways "Object Oriented Perl")
      but for the really useful stuff in the right context start at Stas Bekman's mod_perl guide at <a class="link" href="http://perl.apache.org/guide/" target="_top">http://perl.apache.org/guide/</a>.</p>

      <p>This wonderful book sized document has nothing whatsoever about Icinga, but all about writing Perl programs for
      the embedded Perl interpreter in Apache (i.e. Doug MacEacherns mod_perl).</p>

      <p>The perlembed manpage is essential for context and encouragement.</p>

      <p>On the basis that Lincoln Stein and Doug MacEachern know a thing or two about Perl and embedding Perl, their book
      'Writing Apache Modules with Perl and C' is almost certainly worth looking at.</p>
    </li>
<li class="listitem">
      <p>Be aware that your plugin may return strange values with an ePN and that this is likely to be caused by the problem in
      item #4 above</p>
    </li>
<li class="listitem">
      <p>Be prepared to debug via:</p>

      <div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
          <p>having a test ePN and</p>
        </li>
<li class="listitem">
          <p>adding print statements to your plugin to display variable values to STDERR (can't use STDOUT)</p>
        </li>
<li class="listitem">
          <p>adding print statements to p1.pl to display what ePN thinks your plugin is before it tries to run it (vi)</p>
        </li>
<li class="listitem">
          <p>running the ePN in foreground mode (probably in conjunction with the former recommendations)</p>
        </li>
<li class="listitem">
          <p>use the 'Deparse' module on your plugin to see how the parser has optimised it and what the interpreter will
          actually get. (see 'Constants in Perl' by Sean M. Burke, The Perl Journal, Fall 2001)</p>
        </li>
</ul></div>

      <pre class="screen"> perl -MO::Deparse &lt;your_program&gt;</pre>
    </li>
<li class="listitem">
      <p>Be aware of what ePN is transforming your plugin too, and if all else fails try and debug the transformed
      version.</p>

      <p>As you can see below p1.pl rewrites your plugin as a subroutine called 'hndlr' in the package named
      'Embed::&lt;something_related_to_your_plugin_file_name&gt;'.</p>

      <p>Your plugin may be expecting command line arguments in @ARGV so pl.pl also assigns @_ to @ARGV.</p>

      <p>This in turn gets 'eval' ed and if the eval raises an error (any parse error and run error), the plugin gets chucked
      out.</p>

      <p>The following output shows how a test ePN transformed the <span class="emphasis"><em>check_rpc</em></span> plugin before attempting to
      execute it. Most of the code from the actual plugin is not shown, as we are interested in only the transformations that the
      ePN has made to the plugin). For clarity, transformations are shown in red:</p>

      <pre class="screen">package main;
use subs 'CORE::GLOBAL::exit';
sub CORE::GLOBAL::exit { die "ExitTrap: $_[0] 
(Embed::check_5frpc)"; }

package Embed::check_5frpc; sub hndlr { shift(@_);
@ARGV=@_;
#! /usr/bin/perl -w
#
# check_rpc plugin for Nagios
#
# usage:
#    check_rpc host service
#
# Check if an rpc serice is registered and running
# using rpcinfo - $proto $host $prognum 2&gt;&amp;1 |";
#
# Use these hosts.cfg entries as examples
#
# command[check_nfs]=/some/path/libexec/check_rpc $HOSTADDRESS$ nfs
# service[check_nfs]=NFS;24x7;3;5;5;unix-admin;60;24x7;1;1;1;;check_rpc
#
# initial version: 3 May 2000 by Truongchinh Nguyen and Karl DeBisschop
# current status: $Revision: 1.20 $
#
# Copyright Notice: GPL
#
<span class="emphasis"><em> ... rest of plugin code goes here (it was removed for brevity) ...</em></span>

}</pre>
    </li>
<li class="listitem">
      <p>Don't use 'use diagnostics' in a plugin run by your production ePN. We think it causes__all__ the Perl plugins to
      return CRITICAL.</p>
    </li>
<li class="listitem">
      <p>Consider using a mini embedded Perl C program to check your plugin. This is not sufficient to guarantee your plugin
      will perform Ok with an ePN but if the plugin fails this test it will certainly fail with your ePN. <span class="color"><font color="red">[ A sample mini ePN is included in the <span class="emphasis"><em>contrib/</em></span> directory of the
      Icinga distribution for use in testing Perl plugins. Change to the contrib/ directory and type 'make mini_epn' to
      compile it. It must be executed from the same directory that the p1.pl file resides in (this file is distributed with
      Icinga). ]</font></span></p>
    </li>
</ol></div>
  <a class="indexterm" name="idm140381622206384"></a>
</div>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
<a accesskey="p" href="pluginapi.html">Prev</a> </td>
<td width="20%" align="center"><a accesskey="u" href="ch11.html">Up</a></td>
<td width="40%" align="right"> <a accesskey="n" href="icinga-api.html">Next</a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">11.1. Icinga Plugin API </td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top"> 11.3. No Icinga API to install anymore</td>
</tr>
</table>
</div>
<P class="copyright">© 1999-2009 Ethan Galstad, 2009-2017 Icinga Development Team, https://www.icinga.com</P>
</body>
</html>