diff options
Diffstat (limited to 'src/perl/MMV')
-rw-r--r-- | src/perl/MMV/Changes | 12 | ||||
-rw-r--r-- | src/perl/MMV/GNUmakefile | 67 | ||||
-rw-r--r-- | src/perl/MMV/MANIFEST | 9 | ||||
-rw-r--r-- | src/perl/MMV/MMV.pm | 120 | ||||
-rw-r--r-- | src/perl/MMV/MMV.xs | 381 | ||||
-rw-r--r-- | src/perl/MMV/Makefile.PL | 49 | ||||
-rwxr-xr-x | src/perl/MMV/server.pl | 101 | ||||
-rw-r--r-- | src/perl/MMV/test.pl | 25 | ||||
-rw-r--r-- | src/perl/MMV/typemap | 10 |
9 files changed, 774 insertions, 0 deletions
diff --git a/src/perl/MMV/Changes b/src/perl/MMV/Changes new file mode 100644 index 0000000..a799519 --- /dev/null +++ b/src/perl/MMV/Changes @@ -0,0 +1,12 @@ +Revision history for Perl extension PCP::MMV. + +1.00 Mon Aug 24 08:52:36 EST 2009 + - added stop interface + - added stats_set interface + - fixed incorrect memory free on init + - extend server.pl example to report idle time + - fixed use of av_len return codes (off by one) + +0.01 Fri Jun 12 16:55:20 EST 2009 + - original version + diff --git a/src/perl/MMV/GNUmakefile b/src/perl/MMV/GNUmakefile new file mode 100644 index 0000000..1fc485d --- /dev/null +++ b/src/perl/MMV/GNUmakefile @@ -0,0 +1,67 @@ +#!gmake +# +# Copyright (c) 2009 Aconex. 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; either version 2 of the License, or (at your +# option) any later version. +# +# 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. +# + +TOPDIR = ../../.. +include $(TOPDIR)/src/include/builddefs + +PERLMOD = MMV.pm +INTERFACE = MMV.xs typemap +TESTCODE = test.pl server.pl +PERLDOCS = Changes MANIFEST +LSRCFILES = Makefile.PL $(PERLDOCS) $(PERLMOD) $(INTERFACE) $(TESTCODE) + +LPKGDIRT = PCP-MMV-* MYMETA.yml MYMETA.json +LDIRT = Makefile COPYING MMV.bs MMV.c MMV.o pm_to_blib blib \ + Makefile.old $(LPKGDIRT) + +default: dist + +MAKEMAKER_OPTIONS = INSTALLDIRS=$(PERL_INSTALLDIRS) INSTALLVENDORMAN3DIR=$(PCP_MAN_DIR)/man3 +INSTALLER_OPTIONS = DESTDIR=$$DIST_ROOT + +ifeq ($(TARGET_OS),mingw) +PERLMAKE = dmake.exe +else +PERLMAKE = $(MAKE) +endif + +MMV.o: Makefile MMV.xs + $(PERLMAKE) -f Makefile + +Makefile: COPYING Makefile.PL + $(call PERL_MAKE_MAKEFILE) + +COPYING: + $(LN_S) $(TOPDIR)/COPYING COPYING + +test dist: MMV.o + rm -f $(LPKGDIRT) + $(PERLMAKE) -f Makefile $@ + +include $(BUILDRULES) + +install: default +ifneq "$(PACKAGE_DISTRIBUTION)" "debian" + $(call PERL_GET_FILELIST,$(TOPDIR)/perl-pcp-mmv.list,MMV) + find $$DIST_ROOT -name server.pl -exec chmod 755 '{}' ';' +endif + +install_perl: + $(PERLMAKE) -f Makefile pure_install $(INSTALLER_OPTIONS) + +default_pcp: default + +install_pcp: install + diff --git a/src/perl/MMV/MANIFEST b/src/perl/MMV/MANIFEST new file mode 100644 index 0000000..1551ac8 --- /dev/null +++ b/src/perl/MMV/MANIFEST @@ -0,0 +1,9 @@ +Changes +COPYING +Makefile.PL +MANIFEST +MMV.pm +MMV.xs +server.pl +test.pl +typemap diff --git a/src/perl/MMV/MMV.pm b/src/perl/MMV/MMV.pm new file mode 100644 index 0000000..9f3d7ea --- /dev/null +++ b/src/perl/MMV/MMV.pm @@ -0,0 +1,120 @@ +package PCP::MMV; + +use strict; +use warnings; +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); + +require Exporter; +require DynaLoader; + +@ISA = qw(Exporter DynaLoader); +@EXPORT = qw( + mmv_stats_init mmv_stats_stop mmv_units + mmv_lookup_value_desc + mmv_inc_value mmv_set_value mmv_set_string + mmv_stats_add mmv_stats_inc mmv_stats_set + mmv_stats_add_fallback mmv_stats_inc_fallback + mmv_stats_interval_start mmv_stats_interval_end + mmv_stats_set_string + MMV_FLAG_NOPREFIX MMV_FLAG_PROCESS + MMV_INDOM_NULL + MMV_TYPE_NOSUPPORT + MMV_TYPE_I32 MMV_TYPE_U32 + MMV_TYPE_I64 MMV_TYPE_U64 + MMV_TYPE_FLOAT MMV_TYPE_DOUBLE + MMV_TYPE_STRING MMV_TYPE_ELAPSED + MMV_COUNT_ONE + MMV_SEM_COUNTER MMV_SEM_INSTANT MMV_SEM_DISCRETE + MMV_SPACE_BYTE MMV_SPACE_KBYTE MMV_SPACE_MBYTE + MMV_SPACE_GBYTE MMV_SPACE_TBYTE + MMV_TIME_NSEC MMV_TIME_USEC MMV_TIME_MSEC + MMV_TIME_SEC MMV_TIME_MIN MMV_TIME_HOUR +); +@EXPORT_OK = qw(); +$VERSION = '1.00'; + +sub MMV_INDOM_NULL { 0xffffffff; } + +# flags for pmdammv +sub MMV_FLAG_NOPREFIX { 0x1; } # metric names not prefixed by file name +sub MMV_FLAG_PROCESS { 0x2; } # instrumented process must be running + +# data type of metric values +sub MMV_TYPE_NOSUPPORT { 0xffffffff; } # not implemented in this version +sub MMV_TYPE_I32 { 0; } # 32-bit signed integer +sub MMV_TYPE_U32 { 1; } # 32-bit unsigned integer +sub MMV_TYPE_I64 { 2; } # 64-bit signed integer +sub MMV_TYPE_U64 { 3; } # 64-bit signed integer +sub MMV_TYPE_FLOAT { 4; } # 32-bit floating point +sub MMV_TYPE_DOUBLE { 5; } # 64-bit floating point +sub MMV_TYPE_STRING { 6; } # null-terminated string +sub MMV_TYPE_ELAPSED { 10; } # 64-bit elapsed time + +# units - space scale +sub MMV_SPACE_BYTE { 0; } # bytes +sub MMV_SPACE_KBYTE { 1; } # kilobytes +sub MMV_SPACE_MBYTE { 2; } # megabytes +sub MMV_SPACE_GBYTE { 3; } # gigabytes +sub MMV_SPACE_TBYTE { 4; } # terabytes + +# units - time scale +sub MMV_TIME_NSEC { 0; } # nanoseconds +sub MMV_TIME_USEC { 1; } # microseconds +sub MMV_TIME_MSEC { 2; } # milliseconds +sub MMV_TIME_SEC { 3; } # seconds +sub MMV_TIME_MIN { 4; } # minutes +sub MMV_TIME_HOUR { 5; } # hours + +# units - count scale (for metrics such as count events, syscalls, +# interrupts, etc - these are simply powers of ten and not enumerated here +# (e.g. 6 for 10^6, or -3 for 10^-3). +sub MMV_COUNT_ONE { 0; } # 1 + +# semantics/interpretation of metric values +sub MMV_SEM_COUNTER { 1; } # cumulative counter, monotonic increasing +sub MMV_SEM_INSTANT { 3; } # instantaneous value, continuous domain +sub MMV_SEM_DISCRETE { 4; } # instantaneous value, discrete domain + + +bootstrap PCP::MMV $VERSION; + +1; +__END__ + +=head1 NAME + +PCP::MMV - Perl module for Memory Mapped Value instrumentation + +=head1 SYNOPSIS + + use PCP::MMV; + +=head1 DESCRIPTION + +The PCP::MMV Perl module contains the language bindings for +building Perl programs instrumented with the Performance Co-Pilot +Memory Mapped Value infrastructure - an efficient data transport +mechanism for making performance data from within a Perl program +available as PCP metrics using the MMV PMDA. + +=head1 SEE ALSO + +mmv_stats_init(3), mmv_inc_value(3), mmv_lookup_value_desc(3), +mmv(4) and pmda(3). + +The PCP mailing list pcp@mail.performancecopilot.org can be used for +questions about this module. + +Further details can be found at http://www.performancecopilot.org + +=head1 AUTHOR + +Nathan Scott, E<lt>nathans@debian.orgE<gt> + +Copyright (C) 2009 by Aconex. + +This library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License, version 2 (see +the "COPYING" file in the PCP source tree for further details). + +=cut diff --git a/src/perl/MMV/MMV.xs b/src/perl/MMV/MMV.xs new file mode 100644 index 0000000..2ee6ff8 --- /dev/null +++ b/src/perl/MMV/MMV.xs @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2009 Aconex. 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; either version 2 of the License, or (at your + * option) any later version. + * + * 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. + */ + +#include "pmapi.h" +#include "mmv_stats.h" +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +static int +list_to_metric(SV *list, mmv_metric_t *metric) +{ + int i, len; + SV **entry[8]; + AV *mlist = (AV *) SvRV(list); + + if (SvTYPE((SV *)mlist) != SVt_PVAV) { + warn("metric declaration is not an array reference"); + return -1; + } + len = av_len(mlist) + 1; + if (len < 6) { + warn("too few entries in metric array reference"); + return -1; + } + if (len > 8) { + warn("too many entries in metric array reference"); + return -1; + } + for (i = 0; i < len; i++) + entry[i] = av_fetch(mlist, i, 0); + + strncpy(metric->name, SvPV_nolen(*entry[0]), MMV_NAMEMAX); + metric->name[MMV_NAMEMAX-1] = '\0'; + metric->item = SvIV(*entry[1]); + metric->type = SvIV(*entry[2]); + metric->indom = SvIV(*entry[3]); + i = SvIV(*entry[4]); + memcpy(&metric->dimension, &i, sizeof(pmUnits)); + metric->semantics = SvIV(*entry[5]); + if (len > 6) + metric->shorttext = strdup(SvPV_nolen(*entry[6])); + else + metric->shorttext = NULL; + if (len > 7) + metric->helptext = strdup(SvPV_nolen(*entry[7])); + else + metric->helptext = NULL; + return 0; +} + +static int +list_to_instances(SV *list, mmv_instances_t **insts) +{ + mmv_instances_t *instances; + int i, len; + AV *inlist = (AV *) SvRV(list); + + if (SvTYPE((SV *)inlist) != SVt_PVAV) { + warn("instances declaration is not an array reference"); + return -1; + } + len = av_len(inlist) + 1; + if (len++ % 2) { + warn("odd number of entries in instance array reference"); + return -1; + } + + len /= 2; + instances = (mmv_instances_t *)calloc(len, sizeof(mmv_instances_t)); + if (instances == NULL) { + warn("insufficient memory for instance array"); + return -1; + } + for (i = 0; i < len; i++) { + SV **id = av_fetch(inlist, i*2, 0); + SV **name = av_fetch(inlist, i*2+1, 0); + instances[i].internal = SvIV(*id); + strncpy(instances[i].external, SvPV_nolen(*name), MMV_NAMEMAX); + instances[i].external[MMV_NAMEMAX-1] = '\0'; + } + *insts = instances; + return len; +} + +static int +list_to_indom(SV *list, mmv_indom_t *indom) +{ + int i, len; + SV **entry[4]; + AV *ilist = (AV *) SvRV(list); + + if (SvTYPE((SV *)ilist) != SVt_PVAV) { + warn("indom declaration is not an array reference"); + return -1; + } + len = av_len(ilist) + 1; + if (len < 2) { + warn("too few entries in indom array reference"); + return -1; + } + if (len > 4) { + warn("too many entries in indom array reference"); + return -1; + } + for (i = 0; i < len; i++) + entry[i] = av_fetch(ilist, i, 0); + + indom->serial = SvIV(*entry[0]); + if ((i = list_to_instances(*entry[1], &indom->instances)) < 0) + return -1; + indom->count = i; + if (len > 2) + indom->shorttext = strdup(SvPV_nolen(*entry[2])); + else + indom->shorttext = NULL; + if (len > 3) + indom->helptext = strdup(SvPV_nolen(*entry[3])); + else + indom->helptext = NULL; + return 0; +} + +static int +list_to_metrics(SV *list, mmv_metric_t **metriclist, int *mcount) +{ + mmv_metric_t *metrics; + int i, len; + AV *mlist = (AV *) SvRV(list); + + if (SvTYPE((SV *)mlist) != SVt_PVAV) { + warn("metrics list is not an array reference"); + return -1; + } + len = av_len(mlist) + 1; + metrics = (mmv_metric_t *)calloc(len, sizeof(mmv_metric_t)); + if (metrics == NULL) { + warn("insufficient memory for metrics array"); + return -1; + } + for (i = 0; i < len; i++) { + SV **entry = av_fetch(mlist, i, 0); + if (list_to_metric(*entry, &metrics[i]) < 0) + break; + } + *metriclist = metrics; + *mcount = len; + return (i == len); +} + +static int +list_to_indoms(SV *list, mmv_indom_t **indomlist, int *icount) +{ + mmv_indom_t *indoms; + int i, len; + AV *ilist = (AV *) SvRV(list); + + if (SvTYPE((SV *)ilist) != SVt_PVAV) { + warn("indoms list is not an array reference"); + return -1; + } + len = av_len(ilist) + 1; + indoms = (mmv_indom_t *)calloc(len, sizeof(mmv_indom_t)); + if (indoms == NULL) { + warn("insufficient memory for indoms array"); + return -1; + } + for (i = 0; i < len; i++) { + SV **entry = av_fetch(ilist, i, 0); + if (list_to_indom(*entry, &indoms[i]) < 0) + break; + } + *indomlist = indoms; + *icount = len; + return (i == len); +} + + +MODULE = PCP::MMV PACKAGE = PCP::MMV + +void * +mmv_stats_init(name,cl,fl,metrics,indoms) + char * name + int cl + int fl + SV * metrics + SV * indoms + PREINIT: + int i, j; + int mcount; + int icount; + mmv_metric_t * mlist; + mmv_indom_t * ilist; + CODE: + i = list_to_metrics(metrics, &mlist, &mcount); + j = list_to_indoms(indoms, &ilist, &icount); + + if (i <= 0 || j <= 0) { + warn("mmv_stats_init: bad list conversion: metrics=%d indoms=%d\n", i, j); + RETVAL = NULL; + } + else { + RETVAL = mmv_stats_init(name, cl, fl, mlist, mcount, ilist, icount); + if (RETVAL == NULL) + warn("mmv_stats_init failed: %s\n", osstrerror()); + } + + for (i = 0; i < icount; i++) { + if (ilist[i].shorttext) + free(ilist[i].shorttext); + if (ilist[i].helptext) + free(ilist[i].helptext); + free(ilist[i].instances); + } + if (ilist) + free(ilist); + for (i = 0; i < mcount; i++) { + if (mlist[i].shorttext) + free(mlist[i].shorttext); + if (mlist[i].helptext) + free(mlist[i].helptext); + } + if (mlist) + free(mlist); + + if (!RETVAL) + XSRETURN_UNDEF; + OUTPUT: + RETVAL + +void +mmv_stats_stop(handle,name) + void * handle + char * name + CODE: + mmv_stats_stop(handle, name); + +int +mmv_units(dim_space,dim_time,dim_count,scale_space,scale_time,scale_count) + unsigned int dim_space + unsigned int dim_time + unsigned int dim_count + unsigned int scale_space + unsigned int scale_time + unsigned int scale_count + PREINIT: + pmUnits units; + CODE: + units.pad = 0; + units.dimSpace = dim_space; units.scaleSpace = scale_space; + units.dimTime = dim_time; units.scaleTime = scale_time; + units.dimCount = dim_count; units.scaleCount = scale_count; + RETVAL = *(int *)(&units); + OUTPUT: + RETVAL + +pmAtomValue * +mmv_lookup_value_desc(handle,metric,instance) + void * handle + char * metric + char * instance + CODE: + RETVAL = mmv_lookup_value_desc(handle, metric, instance); + OUTPUT: + RETVAL + +void +mmv_inc_value(handle,atom,value) + void * handle + pmAtomValue * atom + double value + CODE: + mmv_inc_value(handle, atom, value); + +void +mmv_set_value(handle,atom,value) + void * handle + pmAtomValue * atom + double value + CODE: + mmv_set_value(handle, atom, value); + +void +mmv_set_string(handle,atom,string) + void * handle + pmAtomValue * atom + SV * string + PREINIT: + int length; + char * data; + CODE: + data = SvPV_nolen(string); + length = strlen(data); + mmv_set_string(handle, atom, data, length); + +void +mmv_stats_add(handle,metric,instance,count) + void * handle + char * metric + char * instance + double count + CODE: + mmv_stats_add(handle, metric, instance, count); + +void +mmv_stats_inc(handle,metric,instance) + void * handle + char * metric + char * instance + CODE: + mmv_stats_inc(handle, metric, instance); + +void +mmv_stats_set(handle,metric,instance, value) + void * handle + char * metric + char * instance + double value + CODE: + mmv_stats_set(handle, metric, instance, value); + +void +mmv_stats_add_fallback(handle,metric,instance,instance2,count) + void * handle + char * metric + char * instance + char * instance2 + double count + CODE: + mmv_stats_add_fallback(handle, metric, instance, instance2, count); + +void +mmv_stats_inc_fallback(handle,metric,instance,instance2) + void * handle + char * metric + char * instance + char * instance2 + CODE: + mmv_stats_inc_fallback(handle, metric, instance, instance2); + +void +mmv_stats_interval_start(handle,value,metric,instance) + void * handle + pmAtomValue * value + char * metric + char * instance + CODE: + mmv_stats_interval_start(handle, value, metric, instance); + +void +mmv_stats_interval_end(handle, value) + void * handle + pmAtomValue * value + CODE: + mmv_stats_interval_end(handle, value); + +void +mmv_stats_set_string(handle,metric,instance,string) + void * handle + char * metric + char * instance + SV * string + PREINIT: + int length; + char * data; + CODE: + data = SvPV_nolen(string); + length = strlen(data); + mmv_stats_set_strlen(handle, metric, instance, data, length); + diff --git a/src/perl/MMV/Makefile.PL b/src/perl/MMV/Makefile.PL new file mode 100644 index 0000000..6a85129 --- /dev/null +++ b/src/perl/MMV/Makefile.PL @@ -0,0 +1,49 @@ +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +my $ldfrom; +my $inc; +my $libs; +my $lddlflags; +my $cccdlflags; + +if ($ENV{TARGET_OS} eq "mingw") { + $ldfrom = "-L$ENV{PCP_TOPDIR}/src/libpcp/src -L$ENV{PCP_TOPDIR}/src/libpcp_mmv/src -L$ENV{PCP_DIR}\\local\\bin -lpcp_mmv -lpcp MMV.o"; + $inc = "-I$ENV{PCP_TOPDIR}/src/include/pcp -I/usr/include/pcp -I$ENV{PCP_DIR}\\include\\pcp -I$ENV{PCP_DIR}\\c\\include"; + $libs = ["-L$ENV{PCP_DIR}\\local\\bin", '-lpcp_mmv', '-lpcp']; +} +else { + $ldfrom = "MMV.o"; + $inc = "-I$ENV{PCP_TOPDIR}/src/include/pcp -I/usr/include/pcp"; + $libs = ["-L$ENV{PCP_TOPDIR}/src/libpcp_mmv/src -L$ENV{PCP_TOPDIR}/src/libpcp/src -lpcp_mmv -lpcp"]; +} +if ($ENV{TARGET_OS} eq "darwin") { + # standard ones, minus -arch ppc + $lddlflags = "-arch x86_64 -arch i386 -bundle -undefined dynamic_lookup"; +} +else { + $lddlflags = "-shared \$(OPTIMIZE) \$(LDFLAGS)"; +} +if ($ENV{TARGET_OS} eq "solaris") { + # for OpenSolaris Makefile ends up with -KPIC instead of -fPIC otherwise + $cccdlflags = "-fPIC" +} + +WriteMakefile( + NAME => 'PCP::MMV', + AUTHOR => 'Nathan Scott <nathans@debian.org>', + VERSION_FROM => 'MMV.pm', # finds $VERSION + ABSTRACT_FROM => 'MMV.pm', # retrieve abstract from module + C => ['MMV.c'], + OPTIMIZE => '-g', + XSPROTOARG => '-noprototypes', + OBJECT => 'MMV.o', + DEFINE => '-DPERLIO_NOT_STDIO=0 -DPCP_VERSION -DPCP_DEBUG', + LDFROM => $ldfrom, + LDDLFLAGS => $lddlflags, + CCCDLFLAGS => $cccdlflags, + INC => $inc, + LIBS => $libs, + CC => $ENV{"CC"}, + LD => $ENV{"CC"}, +); diff --git a/src/perl/MMV/server.pl b/src/perl/MMV/server.pl new file mode 100755 index 0000000..f62f440 --- /dev/null +++ b/src/perl/MMV/server.pl @@ -0,0 +1,101 @@ +#!/usr/bin/perl +# +# Example server application that demonstrates use of the +# Perl PCP MMV module for runtime instrumentation. +# + +use strict; +use warnings; +use PCP::MMV; +use Time::HiRes qw ( usleep ); + +my @db_instances = ( 0 => "tempdb", 1 => "datadb" ); + +my $db_indom = 1; +my @indoms = ( + [ $db_indom, \@db_instances, + 'Database instances', + 'An instance domain for each database used by this server.', + ], +); + +my @metrics = ( + [ 'response_time.requests', + 1, MMV_TYPE_U64, MMV_INDOM_NULL, + mmv_units(0,0,1,0,0,MMV_COUNT_ONE), MMV_SEM_COUNTER, + 'Number of server requests processed', '' + ], + [ 'response_time.total', + 2, MMV_TYPE_U64, MMV_INDOM_NULL, + mmv_units(0,0,1,0,0,MMV_COUNT_ONE), MMV_SEM_COUNTER, + 'Maximum observed response time in milliseconds', '' + ], + [ 'response_time.maximum', + 3, MMV_TYPE_DOUBLE, MMV_INDOM_NULL, + mmv_units(0,1,0,0,MMV_TIME_MSEC,0), MMV_SEM_INSTANT, + 'Maximum observed response time in milliseconds', '' + ], + [ 'version', + 4, MMV_TYPE_STRING, MMV_INDOM_NULL, + mmv_units(0,0,0,0,0,0), MMV_SEM_DISCRETE, + 'Version number of the server process', '' + ], + [ 'database.transactions.count', + 5, MMV_TYPE_U64, $db_indom, + mmv_units(0,0,1,0,0,MMV_COUNT_ONE), MMV_SEM_COUNTER, + 'Number of requests issued to each database', '' + ], + [ 'database.transactions.time', + 6, MMV_TYPE_U64, $db_indom, + mmv_units(0,1,0,0,MMV_TIME_MSEC,0), MMV_SEM_COUNTER, + 'Total time spent waiting for results from each database', '' + ], + [ 'idletime', + 7, MMV_TYPE_U64, MMV_INDOM_NULL, + mmv_units(0,1,0,0,MMV_TIME_USEC,0), MMV_SEM_COUNTER, + 'Total time spent asleep, in-between requests', '' + ], +); + +my $handle = mmv_stats_init('server', 0, MMV_FLAG_PROCESS, \@metrics, \@indoms); +die("mmv_stats_init failed\n") unless (defined($handle)); + +mmv_stats_set_string($handle, 'version', '', '7.4.2-5'); + +my $maxtime = 0.0; # milliseconds + +for (;;) { + + my $idletime = 0.0; # microseconds + my $dbtime = 0.0; # milliseconds + my $response = 0.0; + + + # start a request ... + + $dbtime = rand 1000; # milliseconds + $response += $dbtime; + mmv_stats_inc($handle, 'database.transactions.count', 'tempdb'); + mmv_stats_add($handle, 'database.transactions.time', 'tempdb', $dbtime); + + # ... more work, involving a second DB request ... + $dbtime = rand 1000; # milliseconds + $response += $dbtime; + mmv_stats_inc($handle, 'database.transactions.count', 'datadb'); + mmv_stats_add($handle, 'database.transactions.time', 'datadb', $dbtime); + + # ... request completed + + + $response += rand 42; # milliseconds + mmv_stats_inc($handle, 'response_time.requests', ''); + mmv_stats_add($handle, 'response_time.total', '', $response); + if ($response > $maxtime) { + $maxtime = $response; + mmv_stats_set($handle, 'response_time.maximum', '', $maxtime); + } + + $idletime = rand 50000; # microseconds + usleep($idletime); + mmv_stats_add($handle, 'idletime', '', $idletime); +} diff --git a/src/perl/MMV/test.pl b/src/perl/MMV/test.pl new file mode 100644 index 0000000..15bd1c6 --- /dev/null +++ b/src/perl/MMV/test.pl @@ -0,0 +1,25 @@ +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl test.pl' +# +# Copyright (c) 2009 Aconex. 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; either version 2 of the License, or (at your +# option) any later version. +# +# 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. +# + +######################### We start with some black magic to print on failure. + +BEGIN { $| = 1; print "1..4\n"; } +END {print "not ok 1\n" unless $loaded;} +use PCP::MMV; +$loaded = 1; +print "ok 1\n"; + +######################### End of black magic. diff --git a/src/perl/MMV/typemap b/src/perl/MMV/typemap new file mode 100644 index 0000000..85f8812 --- /dev/null +++ b/src/perl/MMV/typemap @@ -0,0 +1,10 @@ +###################################################################### +# INPUT/OUTPUT maps +# O_OBJECT -> links an opaque C object to a blessed Perl object. +# +TYPEMAP +pmAtomValue * T_PTROBJ +mmv_indom_t * T_PTROBJ +mmv_metric_t * T_PTROBJ + +###################################################################### |