Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / memcached / memcached_multi_ @ 17f78427

Historique | Voir | Annoter | Télécharger (43,4 ko)

1 06f94086 Matt West
#!/usr/bin/perl
2
#
3 208bfbed Matt West
=head1 MEMCACHED
4 06f94086 Matt West
5 9c93bfd2 Matt West
Memcached Multi - A Plugin to monitor Memcached Servers (Multigraph)
6 06f94086 Matt West
7 9c93bfd2 Matt West
 The common difference between this memcached Munin plugin and others that exists, is that
8
 others don't expose slab information from memcached, so you can better tune your memcached
9
 interaction / stability / etc. With this plugin we leverage multigraph capabilities in
10
 Munin to "hide" the slab information underneath of their parent graphs.
11 06f94086 Matt West
12 9c93bfd2 Matt West
=head1 MUNIN NODE CONFIGURATION
13 06f94086 Matt West
14 9c93bfd2 Matt West
The following configuration information can be overridden by placing environment definitions
15
 like shown here, in a file located in /etc/munin/plugin-conf.d
16 06f94086 Matt West
17 9c93bfd2 Matt West
[memcached_multi_*]
18
 env.host 127.0.0.1                             *default*
19
 env.port 11211                                 *default*
20
 env.timescale 3                                *default*
21
 env.cmds get set delete incr decr touch        *default*
22
 env.leitime -1                                 *default*
23
24
=head2 MUNIN NODE ENVIRONMENT CONFIGURATION EXPLANATION
25
26
 host = host we are going to monitor, this can be used to specify a unix socket.
27 06f94086 Matt West
 port = port we are connecting to, in order to gather stats
28
 timescale = what time frame do we want to format our graphs too
29 9c93bfd2 Matt West
 cmds = cmd types to display on cmd graph, remove cmds you don't want displayed from list.
30
 leitime = setting this to 1 will re-enable slab eviction time graphs, see note below.
31 06f94086 Matt West
32 9c93bfd2 Matt West
=head2 BASIC TROUBLESHOOTING
33 06f94086 Matt West
34
Please make sure you can telnet to your memcache servers and issue the
35
 following commands: stats, stats settings, stats items and stats slabs.
36
37 9c93bfd2 Matt West
=head2 PLUGIN INFORMATION
38
39 06f94086 Matt West
Available Graphs contained in this Plugin
40
41
bytes => This graphs the current network traffic in and out
42
43 9c93bfd2 Matt West
commands => I<MULTIGRAPH> This graphs the current commands being issued to the memcache machine.
44
                                B<Multigraph breaks this down to per slab.>
45
46
conns => This graphs the current, max connections as well as avg conns per sec avg conns per sec
47
            and is derived from total_conns / uptime.
48 06f94086 Matt West
49 9c93bfd2 Matt West
evictions => I<MULTIGRAPH> This graphs the current evictions on the node.
50
                                B<Multigraph breaks this down to per slab.>
51 06f94086 Matt West
52 9c93bfd2 Matt West
items => I<MULTIGRAPH> This graphs the current items and total items in the memcached node.
53
                                B<Multigraph breaks this down to per slab.>
54 06f94086 Matt West
55 9c93bfd2 Matt West
memory => I<MULTIGRAPH> This graphs the current and max memory allocation.
56
                                B<Multigraph breaks this down to per slab.>
57 06f94086 Matt West
58 9c93bfd2 Matt West
unfetched => I<MULTIGRAPH> This graphs the number of items that were never touched by a
59
                get/incr/append/etc before being evicted or expiring from the cache.
60
                                B<Multigraph breaks this down to per slab.>
61 06f94086 Matt West
62
=head1 ADDITIONAL INFORMATION
63
64 9c93bfd2 Matt West
B<NOTE:> The slab plugin for LEI has been disabled since I believe the counters to be inaccurate,
65
    or perhaps not being updated as often I thought they would be. They can be re-enabled by
66
    setting an environment variable, see munin configuration section at the top.
67
68 06f94086 Matt West
You will find that some of the graphs have LEI on them. This was done in order to save room
69
on space for text and stands for B<Last Evicted Item>.
70
71 312bfae1 Matt West
The B<Timescale> variable formats certain graphs based on the following guidelines.
72
 1 => Seconds
73 06f94086 Matt West
 2 => Minutes
74
 3 => Hours  B<*Default*>
75
 4 => Days
76
77
=head1 ACKNOWLEDGEMENTS
78
79 208bfbed Matt West
Thanks to dormando for putting up with me ;)
80 06f94086 Matt West
81
=head1 AUTHOR
82
83 208bfbed Matt West
Matt West < https://github.com/mhwest13/Memcached-Munin-Plugin >
84 06f94086 Matt West
85
=head1 LICENSE
86
87
GPLv2
88
89
=head1 MAGIC MARKERS
90
91 312bfae1 Matt West
#%# family=auto
92
#%# capabilities=autoconf suggest
93 06f94086 Matt West
94
=cut
95
96
use strict;
97 208bfbed Matt West
use warnings;
98 06f94086 Matt West
use IO::Socket;
99
use Munin::Plugin;
100 208bfbed Matt West
use File::Basename;
101
102
if (basename($0) !~ /^memcached_multi_/) {
103
    print "This script needs to be named memcached_multi_ and have symlinks which start the same.\n";
104
    exit 1;
105
}
106 06f94086 Matt West
107 208bfbed Matt West
# tell munin about our multigraph capabilities
108 06f94086 Matt West
need_multigraph();
109
110 208bfbed Matt West
=head1 Variable Declarations
111
112
    This section of code is to declare the variables used throughout the plugin
113
    Some of them are imported as environment variables from munin plugin conf.d
114
    file, others are hashes used for storing information that comes from the
115
    stats commands issued to memcached.
116
117
=cut
118
119
# lets import environment variables for the plugin or use the default
120 06f94086 Matt West
my $host = $ENV{host} || "127.0.0.1";
121
my $port = $ENV{port} || 11211;
122
123 208bfbed Matt West
# This gives us the ability to control the timescale our graphs are displaying.
124
# The default it set to divide by hours, if you want to get seconds set it to 1.
125
# Options: 1 = seconds, 2 = minutes, 3 = hours, 4 = days
126
my $timescale = $ENV{timescale} || 3;
127
128 9c93bfd2 Matt West
# This gives us the ability to turn the Last Evicted Item time slab graph on.
129
# It was removed because I believe the counter / response to be broken but
130
# perhaps this was useful to someone.
131
my $leitime = $ENV{leitime} || -1;
132
133
# This gives us the ability to specify which commands we want to display on the
134
# command graph. Allowing finer control since some environments don't leverage
135
# every command possible in memcached.
136
# Options: get set delete incr decr cas touch flush
137
my $commands = $ENV{cmds} || "get set delete incr decr touch";
138
139 06f94086 Matt West
# This hash contains the information contained in two memcache commands
140
# stats and stats settings.
141 208bfbed Matt West
my %stats;
142 06f94086 Matt West
143 312bfae1 Matt West
# This gives us eviction rates and other hit stats per slab
144 06f94086 Matt West
# We track this so we can see if something was evicted earlier than necessary
145 208bfbed Matt West
my %items;
146 06f94086 Matt West
147
# This gives us the memory size and usage per slab
148 17f78427 Lars Kruse
# We track this so we can see what slab is being used the most and has no free chunks
149 06f94086 Matt West
# so we can re-tune memcached to allocate more pages for the specified chunk size
150 208bfbed Matt West
my %chnks;
151 06f94086 Matt West
152 9c93bfd2 Matt West
# Variable for setting up a quick access map for plugin configurations / version adherence
153
my $globalmap;
154
155 208bfbed Matt West
=head2 Graph Declarations
156
157 9c93bfd2 Matt West
    This block of code builds up all of the graph info for all root / subgraphs.
158 208bfbed Matt West
159
    %graphs: is a container for all of the graph definition information. In here is where you'll
160
             find the configuration information for munin's graphing procedure.
161
    Format:
162
163
    $graph{graph_name} => {
164
        config => {
165
            You'll find the main graph config stored here
166
            { key => value },
167
            { ... },
168
        },
169
        datasrc => [
170
            Name: name given to data value
171
            Attr: Attribute and value, attribute must be valid plugin argument
172
            { name => 'Name', info => 'info about graph', ... },
173
            { ... },
174
        ],
175
    }
176
177
=cut
178 06f94086 Matt West
179
my %graphs;
180
181 208bfbed Matt West
# main graph for memcached item count
182 06f94086 Matt West
$graphs{items} = {
183
    config => {
184
        args => '--base 1000 --lower-limit 0',
185
        vlabel => 'Items in Memcached',
186 78b99b85 dipohl
        category => 'memory',
187 06f94086 Matt West
        title => 'Items',
188 9c93bfd2 Matt West
        info => 'Number of items in use by memcached',
189 06f94086 Matt West
    },
190
    datasrc => [
191
        { name => 'curr_items', label => 'Current Items', min => '0' },
192 312bfae1 Matt West
        { name => 'total_items', label => 'New Items', min => '0', type => 'DERIVE' },
193 06f94086 Matt West
    ],
194
};
195 208bfbed Matt West
# main graph for memcached memory usage
196 06f94086 Matt West
$graphs{memory} = {
197
    config => {
198
        args => '--base 1024 --lower-limit 0',
199
        vlabel => 'Bytes Used',
200 78b99b85 dipohl
        category => 'memory',
201 06f94086 Matt West
        title => 'Memory Usage',
202 9c93bfd2 Matt West
        info => 'Memory consumption of memcached',
203 06f94086 Matt West
    },
204
    datasrc => [
205
        { name => 'limit_maxbytes', draw => 'AREA', label => 'Maximum Bytes Allocated', min => '0' },
206
        { name => 'bytes', draw => 'AREA', label => 'Current Bytes Used', min => '0' },
207
    ],
208
};
209 208bfbed Matt West
# main graph for memcached network usage
210 06f94086 Matt West
$graphs{bytes} = {
211
    config => {
212
        args => '--base 1000',
213
        vlabel => 'bits in (-) / out (+)',
214
        title => 'Network Traffic',
215 78b99b85 dipohl
        category => 'memory',
216 9c93bfd2 Matt West
        info => 'Network traffic in (-) / out (+) of the machine',
217 312bfae1 Matt West
        order => 'bytes_read bytes_written',
218 06f94086 Matt West
    },
219
    datasrc => [
220 9c93bfd2 Matt West
        { name => 'bytes_read', type => 'DERIVE', label => 'Network Traffic coming in (-)',
221
            graph => 'no', cdef => 'bytes_read,8,*', min => '0' },
222
        { name => 'bytes_written', type => 'DERIVE', label => 'Traffic in (-) / out (+)',
223
            negative => 'bytes_read', cdef => 'bytes_written,8,*', min => '0' },
224 06f94086 Matt West
    ],
225
};
226 208bfbed Matt West
# graph for memcached connections
227 06f94086 Matt West
$graphs{conns} = {
228
    config => {
229
        args => '--base 1000 --lower-limit 0',
230
        vlabel => 'Connections per ${graph_period}',
231 78b99b85 dipohl
        category => 'memory',
232 06f94086 Matt West
        title => 'Connections',
233 9c93bfd2 Matt West
        info => 'Number of connections being handled by memcached',
234 312bfae1 Matt West
        order => 'max_conns curr_conns avg_conns',
235 06f94086 Matt West
    },
236
    datasrc => [
237
        { name => 'curr_conns', label => 'Current Connections', min => '0' },
238
        { name => 'max_conns', label => 'Max Connections', min => '0' },
239
        { name => 'avg_conns' , label => 'Avg Connections', min => '0' },
240
    ],
241
};
242 208bfbed Matt West
# main graph for memcached commands issued
243 06f94086 Matt West
$graphs{commands} = {
244
    config => {
245
        args => '--base 1000 --lower-limit 0',
246
        vlabel => 'Commands per ${graph_period}',
247 78b99b85 dipohl
        category => 'memory',
248 06f94086 Matt West
        title => 'Commands',
249 9c93bfd2 Matt West
        info => 'Number of commands being handled by memcached',
250 06f94086 Matt West
    },
251
    datasrc => [
252 9c93bfd2 Matt West
        { name => 'cmd_get', type => 'DERIVE', label => 'Gets',
253
            info => 'Cumulative number of retrieval reqs', min => '0' },
254
        { name => 'cmd_set', type => 'DERIVE', label => 'Sets',
255
            info => 'Cumulative number of storage reqs', min => '0' },
256
        { name => 'cmd_flush', type => 'DERIVE', label => 'Flushes',
257
            info => 'Cumulative number of flush reqs', min => '0' },
258
        { name => 'cmd_touch', type => 'DERIVE', label => 'Touches',
259
            info => 'Cumulative number of touch reqs', min => '0' },
260
        { name => 'get_hits', type => 'DERIVE', label => 'Get Hits',
261
            info => 'Number of keys that were requested and found', min => '0' },
262
        { name => 'get_misses', type => 'DERIVE', label => 'Get Misses',
263
            info => 'Number of keys there were requested and not found', min => '0' },
264
        { name => 'delete_hits', type => 'DERIVE', label => 'Delete Hits',
265
            info => 'Number of delete requests that resulted in a deletion of a key', min => '0' },
266
        { name => 'delete_misses', type => 'DERIVE', label => 'Delete Misses',
267
            info => 'Number of delete requests for missing key', min => '0' },
268
        { name => 'incr_hits', type => 'DERIVE', label => 'Increment Hits',
269
            info => 'Number of successful increment requests', min => '0' },
270
        { name => 'incr_misses', type => 'DERIVE', label => 'Increment Misses',
271
            info => 'Number of unsuccessful increment requests', min => '0' },
272
        { name => 'decr_hits', type => 'DERIVE', label => 'Decrement Hits',
273
            info => 'Number of successful decrement requests', min => '0' },
274
        { name => 'decr_misses', type => 'DERIVE', label => 'Decrement Misses',
275
            info => 'Number of unsuccessful decrement requests', min => '0' },
276
        { name => 'cas_misses', type => 'DERIVE', label => 'CAS Misses',
277
            info => 'Number of Compare and Swap requests against missing keys', min => '0' },
278
        { name => 'cas_hits', type => 'DERIVE', label => 'CAS Hits',
279
            info => 'Number of successful Compare and Swap requests', min => '0' },
280
        { name => 'cas_badval', type => 'DERIVE', label => 'CAS Badval',
281
            info => 'Number of unsuccessful Compare and Swap requests', min => '0' },
282
        { name => 'touch_hits', type => 'DERIVE', label => 'Touch Hits',
283
            info => 'Number of successfully touched keys', min => '0' },
284
        { name => 'touch_misses', type => 'DERIVE', label => 'Touch Misses',
285
            info => 'Number of unsuccessful touch keys', min => '0' },
286 06f94086 Matt West
    ],
287
};
288 208bfbed Matt West
# main graph for memcached eviction rates
289 06f94086 Matt West
$graphs{evictions} = {
290
    config => {
291
        args => '--base 1000 --lower-limit 0',
292
        vlabel => 'Evictions per ${graph_period}',
293 78b99b85 dipohl
        category => 'memory',
294 06f94086 Matt West
        title => 'Evictions',
295 9c93bfd2 Matt West
        info => 'Number of evictions per second',
296 06f94086 Matt West
    },
297
    datasrc => [
298 9c93bfd2 Matt West
        { name => 'evictions', type => 'DERIVE', label => 'Evictions',
299
            info => 'Cumulative Evictions Across All Slabs', min => '0' },
300
        { name => 'evicted_nonzero', type => 'DERIVE', label => 'Evictions prior to Expire',
301
            info => 'Cumulative Evictions forced to expire prior to expiration', min => '0' },
302
        { name => 'reclaimed', type => 'DERIVE', label => 'Reclaimed Items',
303
            info => 'Cumulative Reclaimed Item Entries Across All Slabs', min => '0' },
304 06f94086 Matt West
    ],
305
};
306 9c93bfd2 Matt West
# main graph for memcached eviction rates
307
$graphs{unfetched} = {
308
    config => {
309
        args => '--base 1000 --lower-limit 0',
310
        vlabel => 'Unfetched Items per ${graph_period}',
311 78b99b85 dipohl
        category => 'memory',
312 9c93bfd2 Matt West
        title => 'Unfetched Items',
313 fba800ae Veres Lajos
        info => 'Number of items that were never touched get/incr/append/etc before X occurred',
314 9c93bfd2 Matt West
    },
315
    datasrc => [
316
        { name => 'expired_unfetched', type => 'DERIVE', label => 'Expired Unfetched', min => '0',
317
            info => 'Number of items that expired and never had get/incr/append/etc performed'},
318
        { name => 'evicted_unfetched', type => 'DERIVE', label => 'Evictioned Unfetched', min => '0',
319
            info => 'Number of items that evicted and never had get/incr/append/etc performed'},
320
    ],
321
};
322
# subgraph for breaking memory info down by slab ( subgraph of memory )
323 06f94086 Matt West
$graphs{slabchnks} = {
324
    config => {
325
        args => '--base 1000 --lower-limit 0',
326
        vlabel => 'Available Chunks for this Slab',
327 78b99b85 dipohl
        category => 'memory',
328 06f94086 Matt West
        title => 'Chunk Usage for Slab: ',
329
        info => 'This graph shows you the chunk usage for this memory slab.',
330
    },
331
    datasrc => [
332
        { name => 'total_chunks', label => 'Total Chunks Available', min => '0' },
333
        { name => 'used_chunks', label => 'Total Chunks in Use', min => '0' },
334
        { name => 'free_chunks', label => 'Total Chunks Not in Use (Free)', min => '0' },
335
    ],
336
};
337 9c93bfd2 Matt West
# subgraph for breaking commands down by slab ( subgraph of commands )
338 06f94086 Matt West
$graphs{slabhits} = {
339
    config => {
340
        args => '--base 1000 --lower-limit 0',
341
        vlabel => 'Hits per Slab per ${graph_period}',
342 78b99b85 dipohl
        category => 'memory',
343 06f94086 Matt West
        title => 'Hits for Slab: ',
344
        info => 'This graph shows you the successful hit rate for this memory slab.',
345
    },
346
    datasrc => [
347
        { name => 'get_hits', label => 'Get Requests', type => 'DERIVE', min => '0' },
348
        { name => 'cmd_set', label => 'Set Requests', type => 'DERIVE', min => '0' },
349
        { name => 'delete_hits', label => 'Delete Requests', type => 'DERIVE', min => '0' },
350
        { name => 'incr_hits', label => 'Increment Requests', type => 'DERIVE', min => '0' },
351
        { name => 'decr_hits', label => 'Decrement Requests', type => 'DERIVE', min => '0' },
352 fba800ae Veres Lajos
        { name => 'cas_hits', label => 'Successful CAS Requests', type => 'DERIVE', min => '0' },
353
        { name => 'cas_badval', label => 'UnSuccessful CAS Requests', type => 'DERIVE', min => '0' },
354 9c93bfd2 Matt West
        { name => 'touch_hits', label => 'Touch Requests', type => 'DERIVE', min => '0' },
355 06f94086 Matt West
    ],
356
};
357 9c93bfd2 Matt West
# subgraph for breaking evictions down by slab ( subgraph of evictions )
358 06f94086 Matt West
$graphs{slabevics} = {
359
    config => {
360
        args => '--base 1000 --lower-limit 0',
361
        vlabel => 'Evictions per Slab per ${graph_period}',
362 78b99b85 dipohl
        category => 'memory',
363 06f94086 Matt West
        title => 'Evictions for Slab: ',
364
        info => 'This graph shows you the eviction rate for this memory slab.',
365
    },
366
    datasrc => [
367 9c93bfd2 Matt West
        { name => 'evicted', label => 'Total Evictions', type => 'DERIVE', min => '0',
368
            info => 'Items evicted from memory slab' },
369
        { name => 'evicted_nonzero', type => 'DERIVE', label => 'Evictions from LRU Prior to Expire',
370
            info => 'Items evicted from memory slab before ttl expiration', min => '0' },
371
        { name => 'reclaimed', type => 'DERIVE', label => 'Reclaimed Expired Items',
372
            info => 'Number of times an item was stored in expired memory slab space', min => '0' },
373 06f94086 Matt West
    ],
374
};
375 9c93bfd2 Matt West
# subgraph for showing the time between an item was last evicted and requested ( subgraph of evictions )
376 06f94086 Matt West
$graphs{slabevictime} = {
377
    config => {
378
        args => '--base 1000 --lower-limit 0',
379
        vlabel => ' since Request for LEI',
380 78b99b85 dipohl
        category => 'memory',
381 06f94086 Matt West
        title => 'Eviction Request Time for Slab: ',
382
        info => 'This graph shows you the time since we requested the last evicted item',
383
    },
384
    datasrc => [
385 9c93bfd2 Matt West
        { name => 'evicted_time', label => 'Eviction Time (LEI)',
386
            info => 'Time Since Request for Last Evicted Item', min => '0' },
387 06f94086 Matt West
    ],
388
};
389 9c93bfd2 Matt West
# subgraph for breaking items down by slab ( subgraph of items )
390 06f94086 Matt West
$graphs{slabitems} = {
391
    config => {
392
        args => '--base 1000 --lower-limit 0',
393
        vlabel => 'Items per Slab',
394 78b99b85 dipohl
        category => 'memory',
395 06f94086 Matt West
        title => 'Items in Slab: ',
396
        info => 'This graph shows you the number of items and reclaimed items per slab.',
397
    },
398
    datasrc => [
399 17f78427 Lars Kruse
        { name => 'number', label => 'Items', draw => 'AREA',
400 9c93bfd2 Matt West
            info => 'This is the amount of items stored in this slab', min => '0' },
401 06f94086 Matt West
    ],
402
};
403 9c93bfd2 Matt West
# subgraph for showing the age of the eldest item stored in a slab ( subgraph of items )
404 06f94086 Matt West
$graphs{slabitemtime} = {
405
    config => {
406
        args => '--base 1000 --lower-limit 0',
407
        vlabel => ' since item was stored',
408 78b99b85 dipohl
        category => 'memory',
409 06f94086 Matt West
        title => 'Age of Eldest Item in Slab: ',
410
        info => 'This graph shows you the time of the eldest item in this slab',
411
    },
412
    datasrc => [
413
        { name => 'age', label => 'Eldest Item\'s Age', min => '0' },
414
    ],
415
};
416 9c93bfd2 Matt West
# main graph for memcached eviction rates
417
$graphs{slabunfetched} = {
418
    config => {
419
        args => '--base 1000 --lower-limit 0',
420
        vlabel => 'Unfetched Items per ${graph_period}',
421 78b99b85 dipohl
        category => 'memory',
422 9c93bfd2 Matt West
        title => 'Unfetched Items in Slab: ',
423 fba800ae Veres Lajos
        info => 'Number of items that were never touched get/incr/append/etc before X occurred',
424 9c93bfd2 Matt West
    },
425
    datasrc => [
426
        { name => 'expired_unfetched', type => 'DERIVE', label => 'Expired Unfetched', min => '0',
427
            info => 'Number of items that expired and never had get/incr/append/etc performed'},
428
        { name => 'evicted_unfetched', type => 'DERIVE', label => 'Evictioned Unfetched', min => '0',
429
            info => 'Number of items that evicted and never had get/incr/append/etc performed'},
430
    ],
431
};
432 06f94086 Matt West
433 208bfbed Matt West
=head1 Munin Checks
434 06f94086 Matt West
435 208bfbed Matt West
    These checks look for config / autoconf / suggest params
436
437
=head2 Config Check
438 06f94086 Matt West
439 208bfbed Matt West
    This block of code looks at the argument that is possibly supplied,
440 17f78427 Lars Kruse
    should it be config, it then checks to make sure the plugin
441
    specified exists, assuming it does, it will run the do_config
442 208bfbed Matt West
    subroutine for the plugin specified, otherwise it dies complaining
443
    about an unknown plugin.
444
445
=cut
446
447
if (defined $ARGV[0] && $ARGV[0] eq 'config') {
448
    # Lets get our plugin from the symlink being called up, we'll also verify its a valid
449
    # plugin that we have graph information for
450 06f94086 Matt West
    $0 =~ /memcached_multi_(.+)*/;
451
    my $plugin = $1;
452
    die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
453
    # We need to fetch the stats before we do any config, cause its needed for multigraph
454 208bfbed Matt West
    # subgraphs which use slab information for title / info per slab
455 06f94086 Matt West
    fetch_stats();
456 9c93bfd2 Matt West
    $globalmap = buildglobalmap();
457 06f94086 Matt West
    # Now lets go ahead and print out our config.
458 9c93bfd2 Matt West
    do_config($plugin);
459
    exit 0;
460 06f94086 Matt West
}
461
462 208bfbed Matt West
=head2 Autoconf Check
463 06f94086 Matt West
464 208bfbed Matt West
    This block of code looks at the argument that is possibly supplied,
465
    should it be autoconf, we will attempt to connect to the memcached
466
    service specified on the host:port, upon successful connection it
467
    prints yes, otherwise it prints no.
468 06f94086 Matt West
469 208bfbed Matt West
=cut
470 06f94086 Matt West
471 208bfbed Matt West
if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') {
472
    # Lets attempt to connect to memcached
473
    my $s = get_conn();
474
    # Lets verify that we did connect to memcached
475 06f94086 Matt West
    if (defined($s)) {
476
        print "yes\n";
477
        exit 0;
478
    } else {
479
        print "no (unable to connect to $host\[:$port\])\n";
480
        exit 0;
481
    }
482
}
483
484 208bfbed Matt West
=head2 Suggest Check
485 06f94086 Matt West
486 208bfbed Matt West
    This block of code looks at the argument that is possibly supplied,
487
    should it be suggest, we are going to print the possible plugins
488
    which can be specified. Note we only specify the root graphs for the
489
    multigraphs, since the rest of the subgraphs will appear "behind" the
490
    root graphs. It also attempts to connect to the memcached service to
491
    verify it is infact running.
492 06f94086 Matt West
493 208bfbed Matt West
=cut
494 06f94086 Matt West
495 208bfbed Matt West
if (defined $ARGV[0] && $ARGV[0] eq 'suggest') {
496
    # Lets attempt to connect to memcached
497
    my $s = get_conn();
498
    # Lets check that we did connect to memcached
499 06f94086 Matt West
    if (defined($s)) {
500 9c93bfd2 Matt West
        fetch_stats();
501 06f94086 Matt West
        my @rootplugins = ('bytes','conns','commands','evictions','items','memory');
502 667c62e3 Matt West
        if ($stats{version} !~ /^1\.4\.[0-7]$/) {
503 9c93bfd2 Matt West
            push(@rootplugins, 'unfetched');
504
        }
505 06f94086 Matt West
        foreach my $plugin (@rootplugins) {
506
            print "$plugin\n";
507
        }
508
        exit 0;
509
    } else {
510
        print "no (unable to connect to $host\[:$port\])\n";
511
        exit 0;
512
    }
513
}
514
515 208bfbed Matt West
=head1 Output Subroutines
516 06f94086 Matt West
517 208bfbed Matt West
    Output Subroutine calls to output data values
518 06f94086 Matt West
519 208bfbed Matt West
=head2 fetch_output
520 06f94086 Matt West
521 208bfbed Matt West
    This subroutine is the main call for printing data for the plugin.
522
    No parameters are taken as this is the default call if no arguments
523
    are supplied from the command line.
524 06f94086 Matt West
525 208bfbed Matt West
=cut
526
527
# Well, no arguments were supplied that we know about, so lets print some data
528 9c93bfd2 Matt West
$0 =~ /memcached_multi_(.+)*/;
529
my $plugin = $1;
530
die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
531
fetch_stats();
532
$globalmap = buildglobalmap();
533
fetch_output($plugin);
534 06f94086 Matt West
535 208bfbed Matt West
sub fetch_output {
536 9c93bfd2 Matt West
    my ($plugin) = (@_);
537 06f94086 Matt West
    # Now lets go ahead and print out our output.
538
    my @subgraphs;
539
    if ($plugin eq 'memory') {
540
        @subgraphs = ('slabchnks');
541
        foreach my $slabid(sort{$a <=> $b} keys %chnks) {
542
            print_submulti_output($slabid,$plugin,@subgraphs);
543
        }
544 9c93bfd2 Matt West
        print_subrootmulti_output($plugin);
545 06f94086 Matt West
        print_rootmulti_output($plugin);
546
    } elsif ($plugin eq 'commands') {
547
        @subgraphs = ('slabhits');
548
        foreach my $slabid(sort{$a <=> $b} keys %chnks) {
549
            print_submulti_output($slabid,$plugin,@subgraphs);
550
        }
551 9c93bfd2 Matt West
        print_subrootmulti_output($plugin);
552 06f94086 Matt West
        print_rootmulti_output($plugin);
553
    } elsif ($plugin eq 'evictions') {
554 9c93bfd2 Matt West
        @subgraphs = ('slabevics');
555
        if ($leitime == 1) { push(@subgraphs, 'slabevictime'); }
556 06f94086 Matt West
        foreach my $slabid (sort{$a <=> $b} keys %items) {
557
            print_submulti_output($slabid,$plugin,@subgraphs);
558
        }
559 9c93bfd2 Matt West
        print_subrootmulti_output($plugin);
560 06f94086 Matt West
        print_rootmulti_output($plugin);
561
    } elsif ($plugin eq 'items') {
562
        @subgraphs = ('slabitems','slabitemtime');
563
        foreach my $slabid (sort{$a <=> $b} keys %items) {
564
            print_submulti_output($slabid,$plugin,@subgraphs);
565
        }
566 9c93bfd2 Matt West
        print_subrootmulti_output($plugin);
567
        print_rootmulti_output($plugin);
568
    } elsif ($plugin eq 'unfetched') {
569
        @subgraphs = ('slabunfetched');
570
        foreach my $slabid (sort{$a <=> $b} keys %items) {
571
            print_submulti_output($slabid,$plugin,@subgraphs);
572
        }
573
        print_subrootmulti_output($plugin);
574 06f94086 Matt West
        print_rootmulti_output($plugin);
575
    } else {
576
        print_root_output($plugin);
577
    }
578
579
    return;
580
}
581
582 208bfbed Matt West
=head2 print_root_output
583
584 9c93bfd2 Matt West
    This subroutine prints out the return values for our non-multigraph root graphs.
585
    It takes one parameter $plugin and returns when completed.
586 208bfbed Matt West
587 17f78427 Lars Kruse
        $plugin;    graph we are calling up to print data values for
588 208bfbed Matt West
589
    Example: print_root_output($plugin);
590
591
=cut
592 06f94086 Matt West
593
sub print_root_output {
594 208bfbed Matt West
    # Lets get our plugin, set our graph reference and print out info for Munin
595 06f94086 Matt West
    my ($plugin) = (@_);
596
    my $graph = $graphs{$plugin};
597 208bfbed Matt West
    # The conns plugin has some specific needs, looking for plugin type
598 06f94086 Matt West
    if ($plugin ne 'conns') {
599
        foreach my $dsrc (@{$graph->{datasrc}}) {
600
            my %datasrc = %$dsrc;
601
            while ( my ($key, $value) = each(%datasrc)) {
602
                next if ($key ne 'name');
603
                my $output = $stats{$value};
604
                print "$dsrc->{name}.value $output\n";
605
            }
606
        }
607
    } else {
608
        my $output;
609
        foreach my $dsrc (@{$graph->{datasrc}}) {
610
            my %datasrc = %$dsrc;
611
            while ( my ($key, $value) = each(%datasrc)) {
612
                if ($value eq 'max_conns') {
613
                    $output = $stats{maxconns};
614
                } elsif ($value eq 'curr_conns') {
615
                    $output = $stats{curr_connections};
616
                } elsif ($value eq 'avg_conns') {
617
                    $output = sprintf("%02d", $stats{total_connections} / $stats{uptime});
618
                } else {
619
                    next;
620
                }
621
                print "$dsrc->{name}.value $output\n";
622
            }
623
        }
624
    }
625
    return;
626
}
627
628 208bfbed Matt West
=head2 print_rootmulti_output
629
630 9c93bfd2 Matt West
    This subroutine prints out the return values for our multigraph root graphs.
631
    It takes one parameter $plugin and returns when completed.
632 208bfbed Matt West
633 9c93bfd2 Matt West
        $plugin;    root graph we are calling up to print data values for
634 208bfbed Matt West
635
    Example: print_rootmulti_output($plugin);
636
637
=cut
638 06f94086 Matt West
639
sub print_rootmulti_output {
640 208bfbed Matt West
    # Lets get our plugin, set our graph reference and print out info for Munin
641 06f94086 Matt West
    my ($plugin) = (@_);
642
    my $graph = $graphs{$plugin};
643 9c93bfd2 Matt West
    print "multigraph memcached_multi_$plugin\n";
644
    # Lets print our data values with their appropriate name
645
    foreach my $dsrc (@{$graph->{datasrc}}) {
646
        my $output = 0;
647
        my %datasrc = %$dsrc;
648
        while ( my ($key, $value) = each(%datasrc)) {
649
            next if ($key ne 'name');
650
            next if (($plugin eq 'evictions') && (!exists($globalmap->{globalevics}->{$dsrc->{name}})));
651
            next if (($plugin eq 'commands') && (!exists($globalmap->{globalcmds}->{$dsrc->{name}})));
652
            if (($plugin eq 'evictions') && ($value eq 'evicted_nonzero')) {
653
                foreach my $slabid (sort{$a <=> $b} keys %items) {
654
                    $output += $items{$slabid}->{evicted_nonzero};
655
                }
656
            } else {
657
                $output = $stats{$value};
658
            }
659
            print "$dsrc->{name}.value $output\n";
660
        }
661
    }
662
    return;
663
}
664
665
=head2 print_subrootmulti_output
666
667
    This subroutine prints out the return values for our multigraph root graphs, only this set of
668
    data will display on the subpage made by the multigraph capabilities of munin and the plugin.
669
    It takes one parameter $plugin and returns when completed.
670
671
        $plugin;    root graph we are calling up to print data values for
672
673
    Example: print_rootmulti_output($plugin);
674
675
=cut
676
677
sub print_subrootmulti_output {
678
    # Lets get our plugin, set our graph reference and print out info for Munin
679
    my ($plugin) = (@_);
680
    my $graph = $graphs{$plugin};
681
    if ($plugin eq 'evictions') {
682
        print "multigraph memcached_multi_$plugin.global$plugin\n";
683
    } else {
684
        print "multigraph memcached_multi_$plugin.$plugin\n";
685
    }
686 208bfbed Matt West
    # Lets print our data values with their appropriate name
687 06f94086 Matt West
    foreach my $dsrc (@{$graph->{datasrc}}) {
688
        my $output = 0;
689
        my %datasrc = %$dsrc;
690
        while ( my ($key, $value) = each(%datasrc)) {
691
            next if ($key ne 'name');
692 9c93bfd2 Matt West
            next if (($plugin eq 'evictions') && (!exists($globalmap->{globalevics}->{$dsrc->{name}})));
693
            next if (($plugin eq 'commands') && (!exists($globalmap->{globalcmds}->{$dsrc->{name}})));
694 06f94086 Matt West
            if (($plugin eq 'evictions') && ($value eq 'evicted_nonzero')) {
695
                foreach my $slabid (sort{$a <=> $b} keys %items) {
696
                    $output += $items{$slabid}->{evicted_nonzero};
697
                }
698
            } else {
699
                $output = $stats{$value};
700
            }
701
            print "$dsrc->{name}.value $output\n";
702
        }
703
    }
704
    return;
705
}
706
707 208bfbed Matt West
=head2 print_submulti_output
708
709 9c93bfd2 Matt West
    This subroutine prints out the return values for our multigraph subgraphs. It takes
710
    three parameters $slabid, $plugin, @subgraphs and then rReturns when completed.
711 208bfbed Matt West
712
        $slabid;    slab id that we will use to grab info from and print out
713 9c93bfd2 Matt West
        $plugin;    root graph being called, used for multigraph output and slab id
714 208bfbed Matt West
        @subgraphs; graphs we are actually trying to print data values for
715
716
    Example: print_submulti_output($slabid,$plugin,@subgraphs);
717
718
=cut
719 06f94086 Matt West
720
sub print_submulti_output {
721 208bfbed Matt West
    # Lets get our slabid, plugin, and subgraphs
722 06f94086 Matt West
    my ($slabid,$plugin,@subgraphs) = (@_);
723
    my $currslab = undef;
724 208bfbed Matt West
    # Time to loop over our subgraphs array
725 06f94086 Matt West
    foreach my $sgraph (@subgraphs) {
726 208bfbed Matt West
        # Lets set our graph reference for quick calling, and print some info for munin
727 06f94086 Matt West
        my $graph = $graphs{$sgraph};
728 9c93bfd2 Matt West
        print "multigraph memcached_multi_$plugin.$sgraph\_$slabid\n";
729 208bfbed Matt West
        # Lets figure out what slab info we are trying to call up
730 9c93bfd2 Matt West
        if (($plugin eq 'evictions') || ($plugin eq 'items') || ($plugin eq 'unfetched')) {
731 06f94086 Matt West
            $currslab = $items{$slabid};
732 9c93bfd2 Matt West
        } elsif (($plugin eq 'memory') || ($plugin eq 'commands')) {
733 06f94086 Matt West
            $currslab = $chnks{$slabid};
734
        } else {
735
            return;
736
        }
737 208bfbed Matt West
        # Lets print our data values with their appropriate name
738 06f94086 Matt West
        foreach my $dsrc (@{$graph->{datasrc}}) {
739
            my %datasrc = %$dsrc;
740
            while ( my ($key, $value) = each(%datasrc)) {
741
                next if ($key ne 'name');
742 9c93bfd2 Matt West
                next if (($sgraph eq 'slabevics') && (!exists($globalmap->{slabevics}->{$dsrc->{name}})));
743
                next if (($plugin eq 'commands') && (!exists($globalmap->{slabcmds}->{$dsrc->{name}})));
744 06f94086 Matt West
                my $output = $currslab->{$value};
745
                if (($sgraph eq 'slabevictime') || ($sgraph eq 'slabitemtime')) {
746
                    $output = time_scale('data',$output); ;
747
                }
748
                print "$dsrc->{name}.value $output\n";
749
            }
750
        }
751
    }
752
    return;
753
}
754
755 208bfbed Matt West
=head1 Config Subroutines
756
757
    These subroutines handle the config portion of munin calls.
758
759
=head2 do_config
760 06f94086 Matt West
761 208bfbed Matt West
    This is the main call issued assuming we call up config and plugin specified exists
762
    The subroutine takes one parameter $plugin, and returns when completed.
763
764 9c93bfd2 Matt West
        $plugin; root graph being called
765 208bfbed Matt West
766
    Example: do_config($plugin);
767
768
=cut
769 06f94086 Matt West
770
sub do_config {
771
    my ($plugin) = (@_);
772
    my @subgraphs;
773
    if ($plugin eq 'memory') {
774
        @subgraphs = ('slabchnks');
775
        foreach my $slabid (sort{$a <=> $b} keys %chnks) {
776
            print_submulti_config($slabid,$plugin,@subgraphs);
777
        }
778 9c93bfd2 Matt West
        print_subrootmulti_config($plugin);
779 06f94086 Matt West
        print_rootmulti_config($plugin);
780
    } elsif ($plugin eq 'commands') {
781
        @subgraphs = ('slabhits');
782
        foreach my $slabid (sort{$a <=> $b} keys %chnks) {
783
            print_submulti_config($slabid,$plugin,@subgraphs);
784
        }
785 9c93bfd2 Matt West
        print_subrootmulti_config($plugin);
786 06f94086 Matt West
        print_rootmulti_config($plugin);
787
    } elsif ($plugin eq 'evictions') {
788 9c93bfd2 Matt West
        @subgraphs = ('slabevics');
789
        if ($leitime == 1) { push(@subgraphs, 'slabevictime'); }
790 06f94086 Matt West
        foreach my $slabid (sort{$a <=> $b}  keys %items) {
791
            print_submulti_config($slabid,$plugin,@subgraphs);
792
        }
793 9c93bfd2 Matt West
        print_subrootmulti_config($plugin);
794 06f94086 Matt West
        print_rootmulti_config($plugin);
795
    } elsif ($plugin eq 'items') {
796
        @subgraphs = ('slabitems','slabitemtime');
797
        foreach my $slabid (sort{$a <=> $b} keys %items) {
798
            print_submulti_config($slabid,$plugin,@subgraphs);
799
        }
800 9c93bfd2 Matt West
        print_subrootmulti_config($plugin);
801
        print_rootmulti_config($plugin);
802
    } elsif ($plugin eq 'unfetched') {
803
        @subgraphs = ('slabunfetched');
804
        foreach my $slabid (sort{$a <=> $b}  keys %items) {
805
            print_submulti_config($slabid,$plugin,@subgraphs);
806
        }
807
        print_subrootmulti_config($plugin);
808 06f94086 Matt West
        print_rootmulti_config($plugin);
809
    } else {
810
        print_root_config($plugin);
811
    }
812
813
    return;
814
}
815
816 9c93bfd2 Matt West
=head2 print_root_config
817 208bfbed Matt West
818 9c93bfd2 Matt West
    This subroutine prints out the config information for all of the non-multigraph root graphs.
819
    It takes one parameter, $plugin, returns when completed.
820 208bfbed Matt West
821 9c93bfd2 Matt West
        $plugin;    root graph used for multigraph call
822 208bfbed Matt West
823 9c93bfd2 Matt West
    Example:  print_root_config($plugin);
824 208bfbed Matt West
825
=cut
826 06f94086 Matt West
827 9c93bfd2 Matt West
sub print_root_config {
828
    # Lets get our plugin, set our graph reference and our graph config info
829
    my ($plugin) = (@_);
830
    my $graph = $graphs{$plugin};
831
    my %graphconf = %{$graph->{config}};
832
    # Lets tell munin about the graph we are referencing and print the main config
833
    while ( my ($key, $value) = each(%graphconf)) {
834
        print "graph_$key $value\n";
835
    }
836
    # Lets tell munin about our data values and how to treat them
837
    foreach my $dsrc (@{$graph->{datasrc}}) {
838
        my %datasrc = %$dsrc;
839
        while ( my ($key, $value) = each(%datasrc)) {
840
            next if ($key eq 'name');
841
            print "$dsrc->{name}.$key $value\n";
842 06f94086 Matt West
        }
843
    }
844
    return;
845
}
846
847 208bfbed Matt West
=head2 print_rootmulti_config
848 06f94086 Matt West
849 9c93bfd2 Matt West
    This subroutine prints out the config information for all of the multigraph root graphs.
850 208bfbed Matt West
    It takes one parameter, $plugin, returns when completed.
851 06f94086 Matt West
852 9c93bfd2 Matt West
        $plugin;    root graph used for multigraph call
853 06f94086 Matt West
854 208bfbed Matt West
    Example:  print_rootmulti_config($plugin);
855 06f94086 Matt West
856 208bfbed Matt West
=cut
857 06f94086 Matt West
858 208bfbed Matt West
sub print_rootmulti_config {
859
    # Lets get out plugin, set our graph reference and our graph config info
860
    my ($plugin) = (@_);
861
    my $graph = $graphs{$plugin};
862
    my %graphconf = %{$graph->{config}};
863
    # Lets tell munin about the graph we are referencing and print the main config
864 9c93bfd2 Matt West
    print "multigraph memcached_multi_$plugin\n";
865 06f94086 Matt West
    while ( my ($key, $value) = each(%graphconf)) {
866 78b99b85 dipohl
        if ($key eq 'category') { $value = 'memory' };
867 06f94086 Matt West
        print "graph_$key $value\n";
868
    }
869 208bfbed Matt West
    # Lets tell munin about our data values and how to treat them
870 06f94086 Matt West
    foreach my $dsrc (@{$graph->{datasrc}}) {
871
        my %datasrc = %$dsrc;
872
        while ( my ($key, $value) = each(%datasrc)) {
873
            next if ($key eq 'name');
874 9c93bfd2 Matt West
            next if (($plugin eq 'evictions') && (!exists($globalmap->{globalevics}->{$dsrc->{name}})));
875
            next if (($plugin eq 'commands') && (!exists($globalmap->{globalcmds}->{$dsrc->{name}})));
876 06f94086 Matt West
            print "$dsrc->{name}.$key $value\n";
877
        }
878
    }
879
    return;
880
}
881
882 9c93bfd2 Matt West
=head2 print_subrootmulti_config
883 06f94086 Matt West
884 9c93bfd2 Matt West
    This subroutine prints out the config information for all of the multigraph root graph, only this
885
    graph of the data will display on the subpage made by the multigraph capabilities of munin and
886
    the plugin. It takes one parameter, $plugin, returns when completed.
887 06f94086 Matt West
888 9c93bfd2 Matt West
        $plugin;    root graph used for multigraph call
889 06f94086 Matt West
890 9c93bfd2 Matt West
    Example:  print_rootmulti_config($plugin);
891 06f94086 Matt West
892 208bfbed Matt West
=cut
893 06f94086 Matt West
894 9c93bfd2 Matt West
sub print_subrootmulti_config {
895
    # Lets get out plugin, set our graph reference and our graph config info
896 208bfbed Matt West
    my ($plugin) = (@_);
897
    my $graph = $graphs{$plugin};
898
    my %graphconf = %{$graph->{config}};
899 9c93bfd2 Matt West
    if ($plugin eq 'evictions') {
900
        print "multigraph memcached_multi_$plugin.global$plugin\n";
901
    } else {
902
        print "multigraph memcached_multi_$plugin.$plugin\n";
903
    }
904 06f94086 Matt West
    while ( my ($key, $value) = each(%graphconf)) {
905
        print "graph_$key $value\n";
906
    }
907 208bfbed Matt West
    # Lets tell munin about our data values and how to treat them
908 06f94086 Matt West
    foreach my $dsrc (@{$graph->{datasrc}}) {
909
        my %datasrc = %$dsrc;
910
        while ( my ($key, $value) = each(%datasrc)) {
911
            next if ($key eq 'name');
912 9c93bfd2 Matt West
            next if (($plugin eq 'evictions') && (!exists($globalmap->{globalevics}->{$dsrc->{name}})));
913
            next if (($plugin eq 'commands') && (!exists($globalmap->{globalcmds}->{$dsrc->{name}})));
914 06f94086 Matt West
            print "$dsrc->{name}.$key $value\n";
915
        }
916
    }
917
    return;
918
}
919
920 9c93bfd2 Matt West
=head2 print_submulti_config
921
922
    This subroutine prints out the config information for all of the multigraph subgraphs.
923
    It takes three parameters, $slabid, $plugin and @subgraphs, returns when completed.
924
925
        $slabid;    slab id that we will use to grab info from and print out
926
        $plugin;    root graph being called, used for multigraph output and slab id
927
        @subgraphs; graphs we are actually trying to print data values for
928
929
    Example:  print_submulti_config($slabid,$plugin,@subgraphs);
930
931
=cut
932
933
sub print_submulti_config {
934
    # Lets get our slabid, plugin, and subgraphs
935
    my ($slabid,$plugin,@subgraphs) = (@_);
936
    my ($slabitems,$slabchnks) = undef;
937
    # Time to loop over our subgraphs array
938
    foreach my $sgraph (@subgraphs) {
939
        # Lets set our graph reference, and main graph config for easy handling
940
        my $graph = $graphs{$sgraph};
941
        my %graphconf = %{$graph->{config}};
942 17f78427 Lars Kruse
        # Lets tell munin which graph we are graphing, and what our main graph config info is
943 9c93bfd2 Matt West
        print "multigraph memcached_multi_$plugin.$sgraph\_$slabid\n";
944
        while ( my ($key, $value) = each(%graphconf)) {
945
            if ($key eq 'title') {
946
                print "graph_$key $value" . "$slabid" . " ($chnks{$slabid}->{chunk_size} Bytes)\n";
947
            } elsif (($key eq 'vlabel') && (($sgraph eq 'slabevictime') || ($sgraph eq 'slabitemtime'))) {
948
                $value = time_scale('config',$value);
949
                print "graph_$key $value\n";
950
            } else {
951
                print "graph_$key $value\n";
952
            }
953
        }
954
        # Lets tell munin about our data values and how to treat them
955
        foreach my $dsrc (@{$graph->{datasrc}}) {
956
            my %datasrc = %$dsrc;
957
            while ( my ($key, $value) = each(%datasrc)) {
958
                next if ($key eq 'name');
959
                next if (($sgraph eq 'slabevics') && (!exists($globalmap->{slabevics}->{$dsrc->{name}})));
960
                next if (($plugin eq 'commands') && (!exists($globalmap->{slabcmds}->{$dsrc->{name}})));
961
                print "$dsrc->{name}.$key $value\n";
962
            }
963
        }
964
    }
965
    return;
966
}
967
968 208bfbed Matt West
=head1 Misc Subroutines
969 06f94086 Matt West
970 208bfbed Matt West
    These subroutines are misc ones, and are referenced inside of the code. They
971
    should never be called up by Munin.
972 06f94086 Matt West
973 9c93bfd2 Matt West
=head2 get_conn
974
975
    This subroutine returns a socket connection
976
977
=cut
978
979
sub get_conn {
980
    my $s = undef;
981
982
    # check if we want to use sockets instead of tcp
983
    my ($sock) = ($host =~ /unix:\/\/(.+)*$/);
984
985
    if ($sock) {
986
       $s = IO::Socket::UNIX->new(
987
            Peer     => $sock
988
      );
989
    } else {
990
       $s = IO::Socket::INET->new(
991
            Proto    => "tcp",
992
            PeerAddr => $host,
993
            PeerPort => $port,
994
            Timeout  => 10,
995
       );
996
    }
997
    return $s;
998
}
999
1000 208bfbed Matt West
=head2 fetch_stats
1001 06f94086 Matt West
1002 208bfbed Matt West
    This subroutine fetches the information from memcached and stores it into our
1003
    hashes for later referencing throughout the graph. Returns when completed
1004
1005
=cut
1006 06f94086 Matt West
1007 208bfbed Matt West
sub fetch_stats {
1008
    # Lets try and connect to memcached
1009
    my $s = get_conn();
1010
    # Die if we can't establish a connection to memcached
1011
    die "Error: Unable to Connect to $host\[:$port\]\n" unless $s;
1012
    # Lets print the stats command and store the info from the output
1013
    print $s "stats\r\n";
1014 06f94086 Matt West
    while (my $line = <$s>) {
1015 667c62e3 Matt West
        if ($line =~ /STAT\s(.+?)\s((\w|\d|\S)+)/) {
1016 06f94086 Matt West
            my ($skey,$svalue) = ($1,$2);
1017
            $stats{$skey} = $svalue;
1018
        }
1019
        last if $line =~ /^END/;
1020
    }
1021 208bfbed Matt West
    # Lets print the stats settings command and store the info from the output
1022 06f94086 Matt West
    print $s "stats settings\r\n";
1023
    while (my $line = <$s>) {
1024 667c62e3 Matt West
        if ($line =~ /STAT\s(.+?)\s((\w|\d|\S)+)/) {
1025 06f94086 Matt West
            my ($skey,$svalue) = ($1,$2);
1026 281bd584 Matt West
            if ($skey eq 'evictions') {
1027
                $skey = 'evictions_active';
1028
            }
1029 06f94086 Matt West
            $stats{$skey} = $svalue;
1030
        }
1031
        last if $line =~ /^END/;
1032
    }
1033 208bfbed Matt West
    # Lets print the stats slabs command and store the info from the output
1034 06f94086 Matt West
    print $s "stats slabs\r\n";
1035
    while (my $line = <$s>) {
1036
        if ($line =~ /STAT\s(\d+):(.+)\s(\d+)/) {
1037
            my ($slabid,$slabkey,$slabvalue) = ($1,$2,$3);
1038
            $chnks{$slabid}->{$slabkey} = $slabvalue;
1039
        }
1040
        last if $line =~ /^END/;
1041
    }
1042 208bfbed Matt West
    # Lets print the stats items command and store the info from the output
1043 06f94086 Matt West
    print $s "stats items\r\n";
1044
    while (my $line = <$s>) {
1045
        if ($line =~ /STAT\sitems:(\d+):(.+?)\s(\d+)/) {
1046
            my ($itemid,$itemkey,$itemvalue) = ($1,$2,$3);
1047
            $items{$itemid}->{$itemkey} = $itemvalue;
1048
        }
1049
        last if $line =~ /^END/;
1050
    }
1051
}
1052
1053 208bfbed Matt West
=head2 time_scale
1054
1055
    This subroutine is here for me to adjust the timescale of the time graphs
1056
    for last evicted item and age of eldest item in cache.
1057
1058
        Please note, after long usage I have noticed these counters may not
1059
        be accurate, I believe the developers are aware and have submitted
1060
        a patch upstream.
1061
1062
=cut
1063 06f94086 Matt West
1064
sub time_scale {
1065 208bfbed Matt West
    # Lets get our config option and value to adjust
1066 06f94086 Matt West
    my ($configopt,$origvalue) = (@_);
1067
    my $value;
1068 208bfbed Matt West
    # If config is defined, it returns the config info for time scale
1069
    # If data is defined, it returns the original value after its been adjusted
1070 06f94086 Matt West
    if ($configopt eq 'config') {
1071 312bfae1 Matt West
        if ($timescale == 1) {
1072 06f94086 Matt West
            $value = "Seconds" . $origvalue;
1073
        } elsif ($timescale == 2) {
1074
            $value = "Minutes" . $origvalue;
1075 312bfae1 Matt West
        } elsif (($timescale == 3) || ($timescale > 4) || (!defined($timescale))) {
1076 06f94086 Matt West
            $value = "Hours" . $origvalue;
1077
        } elsif ($timescale == 4) {
1078
            $value = "Days" . $origvalue;
1079
        }
1080
    } elsif ($configopt eq 'data') {
1081 312bfae1 Matt West
        if ($timescale == 1) {
1082 06f94086 Matt West
            $value = sprintf("%02.2f", $origvalue / 1);
1083
        } elsif ($timescale == 2) {
1084
            $value = sprintf("%02.2f", $origvalue / 60);
1085 312bfae1 Matt West
        } elsif (($timescale == 3) || ($timescale > 4) || (!defined($timescale))) {
1086 06f94086 Matt West
            $value = sprintf("%02.2f", $origvalue / 3600);
1087
        } elsif ($timescale == 4) {
1088
            $value = sprintf("%02.2f", $origvalue / 86400);
1089
        }
1090
    } else {
1091
        die "Unknown time_scale option given: either [config/data]\n";
1092
    }
1093
    return $value;
1094
}
1095 9c93bfd2 Matt West
1096
=head2 buildglobalmap
1097
1098
    This subroutine looks at the specified commands inputted, and generates
1099
    a hashref containing two arrays, one for global command keys and one for
1100
    slab command keys.
1101
1102
=cut
1103
1104
sub buildglobalmap {
1105
    my $results;
1106
    my @cmds = split(' ', $commands);
1107
    foreach my $cmd ( @cmds ) {
1108
        if ($cmd eq "get") {
1109
            $results->{globalcmds}->{cmd_get} = 1;
1110
            $results->{globalcmds}->{get_hits} = 1;
1111
            $results->{globalcmds}->{get_misses} = 1;
1112
            $results->{slabcmds}->{get_hits} = 1;
1113
        } elsif ($cmd eq "set" ) {
1114
            $results->{globalcmds}->{cmd_set} = 1;
1115
            $results->{slabcmds}->{cmd_set} = 1;
1116
        } elsif ($cmd eq "delete" ) {
1117
            $results->{globalcmds}->{delete_hits} = 1;
1118
            $results->{globalcmds}->{delete_misses} = 1;
1119
            $results->{slabcmds}->{delete_hits} = 1;
1120
        } elsif ($cmd eq "incr" ) {
1121
            $results->{globalcmds}->{incr_hits} = 1;
1122
            $results->{globalcmds}->{incr_misses} = 1;
1123
            $results->{slabcmds}->{incr_hits} = 1;
1124
        } elsif ($cmd eq "decr" ) {
1125
            $results->{globalcmds}->{decr_hits} = 1;
1126
            $results->{globalcmds}->{decr_misses} = 1;
1127
            $results->{slabcmds}->{decr_hits} = 1;
1128
        } elsif ($cmd eq "cas") {
1129
            $results->{globalcmds}->{cas_hits} = 1;
1130
            $results->{globalcmds}->{cas_misses} = 1;
1131
            $results->{globalcmds}->{cas_badval} = 1;
1132
            $results->{slabcmds}->{cas_hits} = 1;
1133
            $results->{slabcmds}->{cas_badval} = 1;
1134
        } elsif ($cmd eq "touch") {
1135
            if ($stats{version} !~ /^1\.4\.[0-7]$/) {
1136
                $results->{globalcmds}->{cmd_touch} = 1;
1137
                $results->{globalcmds}->{touch_hits} = 1;
1138
                $results->{globalcmds}->{touch_misses} = 1;
1139
                $results->{slabcmds}->{touch_hits} = 1;
1140
            }
1141
        } elsif ($cmd eq "flush") {
1142
            if ($stats{version} !~ /^1\.4\.[0-7]$/) {
1143
                $results->{globalcmds}->{cmd_flush} = 1;
1144
            }
1145
        } else {
1146
            # Do absolutely nothing...
1147
        }
1148
    }
1149
    $results->{globalevics}->{evictions} = 1;
1150
    $results->{globalevics}->{evicted_nonzero}= 1;
1151
    $results->{slabevics}->{evicted} = 1;
1152
    $results->{slabevics}->{evicted_nonzero} = 1;
1153
    if ($stats{version} !~ /^1\.4\.[0-2]$/) {
1154
        $results->{globalevics}->{reclaimed} = 1;
1155
        $results->{slabevics}->{reclaimed} = 1;
1156
    }
1157
    return $results;
1158
}