- Repository
- Munin (2.0)
- Last change
- 2020-03-15
- Graph Categories
- Family
- contrib
- Capabilities
- Language
- Perl
- Authors
zimbra_
Name
zimbra_ - Plugin to monitor all sorts of Zimbra statistics
Applicable Systems
Zimbra 5+ with zmstat statistics enabled.
Text::CSV_XS (perl-Text-CSV_XS from EPEL, for example)
Configuration
Add this to the relevant munin-node config file:
[zimbra*]
group zimbra
The following environment variables are used by this plugin:
csvpath
Path to zmstat csv files (default /opt/zimbra/zmstat)
Bugs/Gotchas
Only reads latest value from the csv, which may be a “last 30 seconds” or “last minute” value, so not a representative “last five minutes” value. The original Zimbra stat charts often use a moving average of some sort.
Author
Erik Inge Bolsø knan@redpill-linpro.com, Redpill Linpro AS
Copyright
Copyright (c) 2009 Erik Inge Bolsø, Redpill Linpro AS
All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 dated June, 1991.
Magic Markers
#%# family=contrib
#%# capabilities=autoconf suggest
#!@@PERL@@
# -*- cperl -*-
#
# Copyright (c) 2009 Erik Inge Bolsø, Redpill Linpro AS
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2 dated June,
# 1991.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA.
=pod
=encoding UTF-8
=head1 NAME
zimbra_ - Plugin to monitor all sorts of Zimbra statistics
=head1 APPLICABLE SYSTEMS
Zimbra 5+ with zmstat statistics enabled.
Text::CSV_XS (perl-Text-CSV_XS from EPEL, for example)
=head1 CONFIGURATION
Add this to the relevant munin-node config file:
[zimbra*]
group zimbra
The following environment variables are used by this plugin:
=over 4
=item csvpath
Path to zmstat csv files (default /opt/zimbra/zmstat)
=back
=head1 BUGS/GOTCHAS
Only reads latest value from the csv, which may be a "last 30 seconds"
or "last minute" value, so not a representative "last five minutes" value.
The original Zimbra stat charts often use a moving average of some sort.
=head1 AUTHOR
Erik Inge Bolsø <knan@redpill-linpro.com>, Redpill Linpro AS
=head1 COPYRIGHT
Copyright (c) 2009 Erik Inge Bolsø, Redpill Linpro AS
All rights reserved. This program is free software; you can
redistribute it and/or modify it under the terms of the GNU General
Public License as published by the Free Software Foundation; version 2
dated June, 1991.
=head1 MAGIC MARKERS
#%# family=contrib
#%# capabilities=autoconf suggest
=cut
use strict;
use warnings;
use Fcntl;
use Tie::File;
my $ret = "";
if (!eval "require Text::CSV_XS;") {
$ret = "No Text::CSV_XS";
}
my $csvpath = ($ENV{'csvpath'} || '/opt/zimbra/zmstat');
# The possible measurements
my %ops =
(
'client_active_connections'
=> {
'vlabel' => 'connections',
'title' => "Client active connections",
'info' => "Mailboxd Active Connections by Client Protocol according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'imap',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'imap_conn',
},
{
'label' => 'imap_ssl',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'imap_ssl_conn',
},
{
'label' => 'pop3',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'pop_conn',
},
{
'label' => 'pop3_ssl',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'pop_ssl_conn',
}, ],
},
'client_request_rate'
=> {
'vlabel' => 'requests/min',
'title' => "Client request rate",
'info' => "Mailboxd Request Rate by Client Protocol according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'soap',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'soap_count',
},
{
'label' => 'imap',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'imap_count',
},
{
'label' => 'pop3',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'pop_count',
}, ],
},
'client_response_time'
=> {
'vlabel' => 'ms',
'title' => "Client response time",
'info' => "Mailboxd Response Time by Client Protocol according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'soap',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'soap_ms_avg',
},
{
'label' => 'imap',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'imap_ms_avg',
},
{
'label' => 'pop3',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'pop_ms_avg',
}, ],
},
'connpool_latency'
=> {
'vlabel' => 'latency (ms)',
'title' => "Connection pool latency",
'info' => "Mailboxd connection pool get latencies according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'database',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'db_conn_ms_avg',
},
{
'label' => 'ldap',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'ldap_dc_ms_avg',
}, ],
},
'jvm_heap_free'
=> {
'vlabel' => 'bytes',
'title' => "JVM heap free",
'info' => "Mailboxd JVM Heap Free according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'total',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'heap_free',
},
{
'label' => 'ps_old_gen',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_ps_old_gen_free',
},
{
'label' => 'cms_old_gen',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_cms_old_gen_free',
},
{
'label' => 'tenured_gen',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_tenured_gen_free',
},
{
'label' => 'train_gen',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_train_gen_free',
},
{
'label' => 'ps_eden',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_ps_eden_space_free',
},
{
'label' => 'ps_survivor',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_ps_survivor_space_free',
},
{
'label' => 'par_eden',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_par_eden_space_free',
},
{
'label' => 'par_survivor',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_par_survivor_space_free',
},
{
'label' => 'eden',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_eden_space_free',
},
{
'label' => 'survivor',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_survivor_space_free',
}, ],
},
'jvm_heap_used'
=> {
'vlabel' => 'bytes',
'title' => "JVM heap used",
'info' => "Mailboxd JVM Heap Used according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'total',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'heap_used',
},
{
'label' => 'ps_old_gen',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_ps_old_gen_used',
},
{
'label' => 'cms_old_gen',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_cms_old_gen_used',
},
{
'label' => 'tenured_gen',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_tenured_gen_used',
},
{
'label' => 'train_gen',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_train_gen_used',
},
{
'label' => 'ps_eden',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_ps_eden_space_used',
},
{
'label' => 'ps_survivor',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_ps_survivor_space_used',
},
{
'label' => 'par_eden',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_par_eden_space_used',
},
{
'label' => 'par_survivor',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_par_survivor_space_used',
},
{
'label' => 'eden',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_eden_space_used',
},
{
'label' => 'survivor',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_survivor_space_used',
}, ],
},
'jvm_major_gc_count'
=> {
'vlabel' => 'Count pr ${graph_period}',
'title' => "JVM major GC count",
'info' => "Mailboxd JVM Major GC Count according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'major',
'type' => 'DERIVE',
'csv' => 'mailboxd.csv',
'csvfield' => 'gc_major_count',
}, ],
},
'jvm_major_gc_time'
=> {
'vlabel' => 'Time (ms) pr ${graph_period}',
'title' => "JVM major GC time",
'info' => "Mailboxd JVM Major GC Time according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'major',
'type' => 'DERIVE',
'csv' => 'mailboxd.csv',
'csvfield' => 'gc_major_ms',
}, ],
},
'jvm_minor_gc_count'
=> {
'vlabel' => 'Count pr ${graph_period}',
'title' => "JVM minor GC count",
'info' => "Mailboxd JVM Minor GC Count according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'minor',
'type' => 'DERIVE',
'csv' => 'mailboxd.csv',
'csvfield' => 'gc_minor_count',
}, ],
},
'jvm_minor_gc_time'
=> {
'vlabel' => 'Time (ms) pr ${graph_period}',
'title' => "JVM minor GC time",
'info' => "Mailboxd JVM Minor GC Time according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'minor',
'type' => 'DERIVE',
'csv' => 'mailboxd.csv',
'csvfield' => 'gc_minor_ms',
}, ],
},
'jvm_permgen'
=> {
'vlabel' => 'bytes',
'title' => "JVM Perm Gen",
'info' => "Mailboxd JVM Permanent Generation and Code Cache according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'ps_perm_gen',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_ps_perm_gen_used',
},
{
'label' => 'perm_gen',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_perm_gen_used',
},
{
'label' => 'cms_perm_gen',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_cms_perm_gen_used',
},
{
'label' => 'code_cache',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_code_cache_used',
},
{
'label' => 'perm_gen_shared_ro',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_perm_gen_[shared-ro]_used',
},
{
'label' => 'perm_gen_shared_rw',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_perm_gen_[shared-rw]_used',
},
{
'label' => 'ps_perm_gen_free',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_ps_perm_gen_free',
},
{
'label' => 'perm_gen_free',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_perm_gen_free',
},
{
'label' => 'cms_perm_gen_free',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_cms_perm_gen_free',
},
{
'label' => 'code_cache_free',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_code_cache_free',
},
{
'label' => 'perm_gen_shared_ro_free',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_perm_gen_[shared-ro]_free',
},
{
'label' => 'perm_gen_shared_rw_free',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mpool_perm_gen_[shared-rw]_free',
}, ],
},
'lmtp_throughput'
=> {
'vlabel' => 'bytes/min',
'title' => "LMTP throughput",
'info' => "Mailboxd LMTP Throughput according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'received',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'lmtp_rcvd_bytes',
},
{
'label' => 'delivered',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'lmtp_dlvd_bytes',
}, ],
},
'lmtp_delivery_rate'
=> {
'vlabel' => 'msgs/min',
'title' => "LMTP delivery rate",
'info' => "Mailboxd LMTP Delivery Rate according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'received',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'lmtp_rcvd_msgs',
},
{
'label' => 'delivered',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'lmtp_dlvd_msgs',
},
{
'label' => 'rcvd_rcpt',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'lmtp_rcvd_rcpt',
'info' => 'received messages * recipients',
}, ],
},
'lucene_cachehit'
=> {
'vlabel' => 'hitrate %',
'title' => "Lucene cache hitrate",
'info' => "Mailboxd Lucene IndexWriterCache hitrate according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'total',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'idx_wrt_opened',
'csvfield2'=> 'idx_wrt_opened_cache_hit',
'graph' => 'off'
},
{
'label' => 'hit',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'idx_wrt_opened_cache_hit',
'draw' => 'AREA',
'cdef' => 'hit,total,/,100,*'
}, ],
},
'lucene_io'
=> {
'vlabel' => 'bytes',
'title' => "Lucene I/O",
'info' => "Mailboxd lucene I/O according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'write',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'idx_bytes_written',
},
{
'label' => 'read',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'idx_bytes_read',
}, ],
},
'lucene_writers'
=> {
'vlabel' => 'writers',
'title' => "Lucene index writers",
'info' => "Mailboxd dirty lucene index writers according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'writers',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'idx_wrt_avg',
}, ],
},
'mailbox_add_latency'
=> {
'vlabel' => 'latency (ms)',
'title' => "Mailbox add latency",
'info' => "Mailboxd Mailbox Add Latency (Delivery Speed) according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'latency',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mbox_add_msg_ms_avg',
}, ],
},
'mailbox_add_rate'
=> {
'vlabel' => 'msgs/min',
'title' => "Mailbox add rate",
'info' => "Mailboxd Mailbox Add Rate (Delivery Rate) according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'adds',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mbox_add_msg_count',
}, ],
},
'mailbox_cachehit'
=> {
'vlabel' => 'hitrate %',
'title' => "Mailbox cache hitrate",
'info' => "Mailboxd Mailbox Cache hitrate according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'hit',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mbox_cache',
}, ],
},
'mailbox_itemblob_cachehit'
=> {
'vlabel' => 'hitrate %',
'title' => "Mailbox item/blob cache",
'info' => "Mailboxd Mailbox Item/Blob Cache hitrate according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'blob',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mbox_msg_cache',
},
{
'label' => 'metadata',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mbox_item_cache',
}, ],
},
# what does this actually measure? Hovers around 1 on an idle test server.
'mailbox_get_count'
=> {
'vlabel' => 'count',
'title' => "Mailbox get count",
'info' => "Mailboxd Mailbox Get Count according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'get',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mbox_get_count',
}, ],
},
'mailbox_get_latency'
=> {
'vlabel' => 'latency (ms)',
'title' => "Mailbox get latency",
'info' => "Mailboxd Mailbox Get Latency according to zmstat/mailboxd.csv",
'fields' => [ {
'label' => 'latency',
'type' => 'GAUGE',
'csv' => 'mailboxd.csv',
'csvfield' => 'mbox_get_ms_avg',
}, ],
},
'postfix_queue'
=> {
'vlabel' => 'Messages queued',
'title' => "Postfix messages queued",
'info' => "Postfix messages queued according to zmstat/mtaqueue.csv",
'fields' => [ {
'label' => 'messages',
'type' => 'GAUGE',
'csv' => 'mtaqueue.csv',
'csvfield' => 'requests',
}, ],
},
'process_cpu'
=> {
'vlabel' => 'percent cpu',
'title' => "Process CPU usage",
'info' => "Process CPU usage according to zmstat/proc.csv",
'fields' => [ {
'label' => 'mailbox',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'mailbox-total-cpu',
},
{
'label' => 'mysql',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'mysql-total-cpu',
},
{
'label' => 'convertd',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'convertd-total-cpu',
},
{
'label' => 'ldap',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'ldap-total-cpu',
},
{
'label' => 'postfix',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'postfix-total-cpu',
},
{
'label' => 'amavis',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'amavis-total-cpu',
},
{
'label' => 'clam',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'clam-total-cpu',
},
{
'label' => 'stats',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'stats-total-cpu',
}, ],
},
'process_mem_total'
=> {
'vlabel' => 'MB',
'title' => "Process Total Memory",
'info' => "Process Total memory usage according to zmstat/proc.csv",
'fields' => [ {
'label' => 'mailbox',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'mailbox-totalMB',
},
{
'label' => 'mysql',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'mysql-totalMB',
},
{
'label' => 'convertd',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'convertd-totalMB',
},
{
'label' => 'ldap',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'ldap-totalMB',
},
{
'label' => 'postfix',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'postfix-totalMB',
},
{
'label' => 'amavis',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'amavis-totalMB',
},
{
'label' => 'clam',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'clam-totalMB',
},
{
'label' => 'stats',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'stats-totalMB',
}, ],
},
'process_mem_rss'
=> {
'vlabel' => 'MB',
'title' => "Process Resident Memory",
'info' => "Process resident memory (RSS) according to zmstat/proc.csv",
'fields' => [ {
'label' => 'mailbox',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'mailbox-rssMB',
},
{
'label' => 'mysql',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'mysql-rssMB',
},
{
'label' => 'convertd',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'convertd-rssMB',
},
{
'label' => 'ldap',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'ldap-rssMB',
},
{
'label' => 'postfix',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'postfix-rssMB',
},
{
'label' => 'amavis',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'amavis-rssMB',
},
{
'label' => 'clam',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'clam-rssMB',
},
{
'label' => 'stats',
'type' => 'GAUGE',
'csv' => 'proc.csv',
'csvfield' => 'stats-rssMB',
}, ],
},
);
# Config subroutine
sub config {
my $action = shift;
if (!(exists $ops{$action})) { die "wrong symlinked name, $action is not implemented\n"; }
print <<EOF;
graph_args --base 1000 -l 0
graph_vlabel $ops{$action}->{'vlabel'}
graph_title $ops{$action}->{'title'}
graph_category Zimbra
graph_info $ops{$action}->{'info'}
EOF
my $tmpfield = $ops{$action}->{'fields'};
foreach my $field ( @$tmpfield )
{
my $label = $field->{'label'};
print "$label.label $label\n";
print "$label.type $field->{'type'}\n";
print "$label.min 0\n";
if (exists $field->{'graph'}) { print "$label.graph $field->{'graph'}\n"; }
if (exists $field->{'info'}) { print "$label.info $field->{'info'}\n"; }
if (exists $field->{'draw'}) { print "$label.draw $field->{'draw'}\n"; }
if (exists $field->{'cdef'}) { print "$label.cdef $field->{'cdef'}\n"; }
}
}
my $op;
if ($0 =~ /zimbra_([\w\d_]+)$/)
{
$op = $1;
}
if ($ARGV[0]) {
if ($ARGV[0] eq "config") {
if ($op) {
&config ($op);
} else {
die ("Can't run config without a symlinked name\n");
}
} elsif ($ARGV[0] eq "autoconf") {
if ($ret ne "") {
print "no ($ret)\n";
}
elsif (chdir $csvpath)
{
print "yes\n";
}
else
{
print "no (chdir to $csvpath failed)\n";
}
} elsif ($ARGV[0] eq "suggest") {
foreach my $key ( keys %ops )
{
print "$key\n";
}
}
exit 0;
}
# We won't run this without parameters.
die ("Can't run without a symlinked name\n") if $0 =~ /zimbra_$/;
my @cached_csvfields = ();
my $tmpfield = $ops{$op}->{'fields'};
foreach my $field ( @$tmpfield )
{
my $label = $field->{'label'};
my $csv = Text::CSV_XS->new ( { 'allow_whitespace' => 1 } );
my $error;
if (tie my @file, 'Tie::File', $csvpath . "/" . $field->{'csv'}, mode => O_RDONLY)
{
# parse the csv header line for the interesting field
my $status = $csv->parse($file[0]);
my @csvfields = $csv->fields();
my $csvindex = 0; $csvindex++ until $csvindex > $#csvfields or $csvfields[$csvindex] eq $field->{'csvfield'};
if ($csvindex > $#csvfields) { $error = 1; goto FIELDERR; }
my $csvindex2;
if (exists $field->{'csvfield2'})
{
$csvindex2 = 0; $csvindex2++ until $csvindex2 > $#csvfields or $csvfields[$csvindex2] eq $field->{'csvfield2'};
if ($csvindex2 > $#csvfields) { $error = 1; goto FIELDERR; }
}
unless ($#cached_csvfields > -1)
{
# blindly use last line of the csv, for now
$status = $csv->parse($file[-1]);
@cached_csvfields = $csv->fields();
}
# empty csv field => undef
if ($cached_csvfields[$csvindex] eq "") { $error = 1; goto FIELDERR; }
if (defined $csvindex2)
{
print "$label.value " . ( $cached_csvfields[$csvindex] + $cached_csvfields[$csvindex2] ). "\n";
} else {
print "$label.value " . $cached_csvfields[$csvindex] . "\n";
}
} else { $error = 1; }
FIELDERR:
if ($error) {
print "$label.value UNDEF\n" ;
}
}