← Index
NYTProf Performance Profile   « line view »
For flows_to_es.pl
  Run on Mon May 9 23:27:59 2016
Reported on Mon May 9 23:28:09 2016

Filename/opt/flows/lib/lib/perl5/InfluxDB/LineProtocol.pm
StatementsExecuted 25 statements in 2.21ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
111692µs1.15msInfluxDB::LineProtocol::::BEGIN@10InfluxDB::LineProtocol::BEGIN@10
11120µs20µsInfluxDB::LineProtocol::::importInfluxDB::LineProtocol::import
11115µs30µsInfluxDB::LineProtocol::::BEGIN@2InfluxDB::LineProtocol::BEGIN@2
1119µs14µsInfluxDB::LineProtocol::::BEGIN@3InfluxDB::LineProtocol::BEGIN@3
1118µs54µsInfluxDB::LineProtocol::::BEGIN@9InfluxDB::LineProtocol::BEGIN@9
1118µs21µsInfluxDB::LineProtocol::::BEGIN@37InfluxDB::LineProtocol::BEGIN@37
1111µs1µsInfluxDB::LineProtocol::::CORE:matchInfluxDB::LineProtocol::CORE:match (opcode)
0000s0sInfluxDB::LineProtocol::::_data2line_0_9_2InfluxDB::LineProtocol::_data2line_0_9_2
0000s0sInfluxDB::LineProtocol::::_format_keyInfluxDB::LineProtocol::_format_key
0000s0sInfluxDB::LineProtocol::::_format_valueInfluxDB::LineProtocol::_format_value
0000s0sInfluxDB::LineProtocol::::_line2data_0_9_2InfluxDB::LineProtocol::_line2data_0_9_2
0000s0sInfluxDB::LineProtocol::::data2lineInfluxDB::LineProtocol::data2line
0000s0sInfluxDB::LineProtocol::::line2dataInfluxDB::LineProtocol::line2data
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package InfluxDB::LineProtocol;
2234µs244µs
# spent 30µs (15+15) within InfluxDB::LineProtocol::BEGIN@2 which was called: # once (15µs+15µs) by main::BEGIN@207 at line 2
use strict;
# spent 30µs making 1 call to InfluxDB::LineProtocol::BEGIN@2 # spent 15µs making 1 call to strict::import
3246µs219µs
# spent 14µs (9+5) within InfluxDB::LineProtocol::BEGIN@3 which was called: # once (9µs+5µs) by main::BEGIN@207 at line 3
use warnings;
# spent 14µs making 1 call to InfluxDB::LineProtocol::BEGIN@3 # spent 5µs making 1 call to warnings::import
4
51700nsour $VERSION = '1.007';
6
7# ABSTRACT: Write and read InfluxDB LineProtocol
8
9233µs2100µs
# spent 54µs (8+46) within InfluxDB::LineProtocol::BEGIN@9 which was called: # once (8µs+46µs) by main::BEGIN@207 at line 9
use Carp qw(croak);
# spent 54µs making 1 call to InfluxDB::LineProtocol::BEGIN@9 # spent 46µs making 1 call to Exporter::import
102250µs21.33ms
# spent 1.15ms (692µs+454µs) within InfluxDB::LineProtocol::BEGIN@10 which was called: # once (692µs+454µs) by main::BEGIN@207 at line 10
use Time::HiRes qw(gettimeofday);
# spent 1.15ms making 1 call to InfluxDB::LineProtocol::BEGIN@10 # spent 179µs making 1 call to Time::HiRes::import
11
1212µsmy %versions = (
13 'v0.9.2' => '_0_9_2',
14);
15
16
# spent 20µs (20+1) within InfluxDB::LineProtocol::import which was called: # once (20µs+1µs) by main::BEGIN@207 at line 207 of flows_to_es.pl
sub import {
171600ns my $class = shift;
181700ns my $caller = caller();
19
20
211100ns my @to_export;
221100ns my $version;
2311µs foreach my $param (@_) {
2411µs if ($param eq 'data2line' || $param eq 'line2data') {
25 push(@to_export,$param);
26 }
2719µs11µs if ($param =~ /^v[\d\.]+$/ && $versions{$param}) {
# spent 1µs making 1 call to InfluxDB::LineProtocol::CORE:match
28 $version = $versions{$param};
29 }
30 }
31
3214µs foreach my $function (@to_export) {
331300ns my $target = $function;
341100ns $function = '_'.$function.$version if $version;
35
36 {
3731.82ms234µs
# spent 21µs (8+13) within InfluxDB::LineProtocol::BEGIN@37 which was called: # once (8µs+13µs) by main::BEGIN@207 at line 37
no strict 'refs';
# spent 21µs making 1 call to InfluxDB::LineProtocol::BEGIN@37 # spent 13µs making 1 call to strict::unimport
3814µs *{"$caller\::$target"} = \&$function;
39 }
40 }
41
42}
43
44sub _format_key {
45 my $k = shift;
46
47 $k =~ s/([, ])/\\$1/g;
48
49 return $k;
50}
51
52sub _format_value {
53 my $k = shift;
54 my $v = shift;
55
56 if ( $v =~ /^(-?\d+)(?:i?)$/ ) {
57 $v = $1 . 'i';
58 }
59 elsif ( $v =~ /^[Ff](?:ALSE|alse)?$/ ) {
60 $v = 'FALSE';
61 }
62 elsif ( $v =~ /^[Tt](?:RUE|rue)?$/ ) {
63 $v = 'TRUE';
64 }
65 elsif ( $v =~ /^-?\d+(?:\.\d+)?(?:e-?\d+)?$/ ) {
66 # pass it on, no mod
67 }
68 else {
69 # string actually, but this should be quoted differently?
70 $v =~ s/"/\\"/g;
71 $v = '"' . $v . '"';
72 }
73
74 return $v;
75}
76
77sub data2line {
78 my ( $measurement, $values, $tags, $timestamp ) = @_;
79
80 if ( @_ == 1 ) {
81 # no $fields, so assume we already got a line
82 return $measurement;
83 }
84
85 my $key = $measurement;
86 $key =~ s/([, ])/\\$1/g;
87
88 # $tags has to be a hashref, if it's not, we dont have tags, so it's the timestamp
89 if ( defined $tags ) {
90 if ( ref($tags) eq 'HASH' ) {
91 my @tags;
92 foreach my $k ( sort keys %$tags )
93 { # Influx wants the tags presorted
94 # TODO check if sorting algorithm matches
95 # http://golang.org/pkg/bytes/#Compare
96 my $v = $tags->{$k};
97 next unless defined $v;
98 $k =~ s/([, ])/\\$1/g;
99 $v =~ s/([, ])/\\$1/g;
100 push( @tags, $k . '=' . $v );
101 }
102 $key .= join( ',', '', @tags ) if @tags;
103 }
104 elsif ( !ref($tags) ) {
105 $timestamp = $tags;
106 }
107 }
108
109 if ($timestamp) {
110 croak("$timestamp does not look like an epoch timestamp")
111 unless $timestamp =~ /^\d+$/;
112 if ( length($timestamp) < 19 ) {
113 my $missing = 19 - length($timestamp);
114 my $zeros = 0 x $missing;
115 $timestamp .= $zeros;
116 }
117 }
118 else {
119 # Get time of day returns (seconds, microseconds)
120 # $timestamp needs to be nanoseconds
121 # it must also be a string to avoid conversion to sci notations
122 $timestamp = sprintf "%s%06d000", gettimeofday();
123 }
124
125 # If values is not a hashref, convert it into one
126 $values = { value => $values } if (not ref($values));
127
128 my @fields;
129 foreach my $k ( sort keys %$values ) {
130 my $v = $values->{$k};
131
132 my $esc_k = _format_key($k);
133 my $esc_v = _format_value($k, $v);
134
135 push( @fields, $esc_k . '=' . $esc_v );
136 }
137 my $fields = join( ',', @fields );
138
139 return sprintf( "%s %s %s", $key, $fields, $timestamp );
140}
141
142sub line2data {
143 my $line = shift;
144 chomp($line);
145
146 $line =~ s/\\ /ESCAPEDSPACE/g;
147 $line =~ s/\\,/ESCAPEDCOMMA/g;
148 $line =~ s/\\"/ESCAPEDDBLQUOTE/g;
149
150 $line=~/^(.*?) (.*) (.*)$/;
151 my ($key, $fields, $timestamp) = ( $1, $2, $3);
152
153 my ( $measurement, @taglist ) = split( /,/, $key );
154 $measurement =~ s/ESCAPEDSPACE/ /g;
155 $measurement =~ s/ESCAPEDCOMMA/,/g;
156
157 my $tags;
158 foreach my $tagset (@taglist) {
159 $tagset =~ s/ESCAPEDSPACE/ /g;
160 $tagset =~ s/ESCAPEDCOMMA/,/g;
161 my ( $k, $v ) = split( /=/, $tagset );
162 $tags->{$k} = $v;
163 }
164
165 my $values;
166 my @strings;
167 if ($fields =~ /"/) {
168 my $cnt=0;
169 $fields=~s/"(.*?)"/push(@strings, $1); 'ESCAPEDSTRING_'.$cnt++;/ge;
170 }
171 foreach my $valset ( split( /,/, $fields ) ) {
172 $valset =~ s/ESCAPEDSPACE/ /g;
173 $valset =~ s/ESCAPEDCOMMA/,/g;
174 my ( $k, $v ) = split( /=/, $valset );
175 $v =~ s/ESCAPEDSTRING_(\d+)/$strings[$1]/ge;
176 $v =~ s/ESCAPEDDBLQUOTE/"/g;
177 $v =~ s/^(-?\d+)i$/$1/;
178 $values->{$k} = $v;
179 }
180
181 return ( $measurement, $values, $tags, $timestamp );
182}
183
184sub _data2line_0_9_2 {
185 my ( $measurement, $values, $tags, $timestamp ) = @_;
186
187 if ( @_ == 1 ) {
188 # no $fields, so assume we already got a line
189 return $measurement;
190 }
191
192 my $key = $measurement;
193 $key =~ s/([, ])/\\$1/g;
194
195 # $tags has to be a hashref, if it's not, we dont have tags, so it's the timestamp
196 if ( defined $tags ) {
197 if ( ref($tags) eq 'HASH' ) {
198 my @tags;
199 foreach my $k ( sort keys %$tags )
200 { # Influx wants the tags presorted
201 # TODO check if sorting algorithm matches
202 # http://golang.org/pkg/bytes/#Compare
203 my $v = $tags->{$k};
204 next unless defined $v;
205 $k =~ s/([, ])/\\$1/g;
206 $v =~ s/([, ])/\\$1/g;
207 push( @tags, $k . '=' . $v );
208 }
209 $key .= join( ',', '', @tags ) if @tags;
210 }
211 elsif ( !ref($tags) ) {
212 $timestamp = $tags;
213 }
214 }
215
216 if ($timestamp) {
217 croak("$timestamp does not look like an epoch timestamp")
218 unless $timestamp =~ /^\d+$/;
219 if ( length($timestamp) < 19 ) {
220 my $missing = 19 - length($timestamp);
221 my $zeros = 0 x $missing;
222 $timestamp .= $zeros;
223 }
224 }
225 else {
226 $timestamp = join( '', gettimeofday(), '000' );
227 $timestamp .= '0' if length($timestamp) < 19;
228 }
229
230 # If values is not a hashref, convert it into one
231 $values = { value => $values } if (not ref($values));
232
233 my @fields;
234 foreach my $k ( sort keys %$values ) {
235 my $v = $values->{$k};
236 $k =~ s/([, ])/\\$1/g;
237
238 if (
239 # positive & negativ ints, exponentials, use Regexp::Common?
240 $v !~ /^-?\d+(?:\.\d+)?(?:e-?\d+)?$/
241 &&
242 # perl 5.12 Regexp::Assemble->new->add(qw(t T true TRUE f F false FALSE))->re;
243 $v !~ /^(?:F(?:ALSE)?|f(?:alse)?|T(?:RUE)?|t(?:rue)?)$/
244 )
245 {
246 $v =~ s/"/\\"/g;
247 $v = '"' . $v . '"';
248 }
249 push( @fields, $k . '=' . $v );
250 }
251 my $fields = join( ',', @fields );
252
253 return sprintf( "%s %s %s", $key, $fields, $timestamp );
254}
255
256sub _line2data_0_9_2 {
257 my $line = shift;
258 chomp($line);
259
260 $line =~ s/\\ /ESCAPEDSPACE/g;
261 $line =~ s/\\,/ESCAPEDCOMMA/g;
262 $line =~ s/\\"/ESCAPEDDBLQUOTE/g;
263
264 $line=~/^(.*?) (.*) (.*)$/;
265 my ($key, $fields, $timestamp) = ( $1, $2, $3);
266
267 my ( $measurement, @taglist ) = split( /,/, $key );
268 $measurement =~ s/ESCAPEDSPACE/ /g;
269 $measurement =~ s/ESCAPEDCOMMA/,/g;
270
271 my $tags;
272 foreach my $tagset (@taglist) {
273 $tagset =~ s/ESCAPEDSPACE/ /g;
274 $tagset =~ s/ESCAPEDCOMMA/,/g;
275 my ( $k, $v ) = split( /=/, $tagset );
276 $tags->{$k} = $v;
277 }
278
279 my $values;
280 my @strings;
281 if ($fields =~ /"/) {
282 my $cnt=0;
283 $fields=~s/"(.*?)"/push(@strings, $1); 'ESCAPEDSTRING_'.$cnt++;/ge;
284 }
285 foreach my $valset ( split( /,/, $fields ) ) {
286 $valset =~ s/ESCAPEDSPACE/ /g;
287 $valset =~ s/ESCAPEDCOMMA/,/g;
288 my ( $k, $v ) = split( /=/, $valset );
289 $v =~ s/ESCAPEDSTRING_(\d+)/$strings[$1]/ge;
290 $v =~ s/ESCAPEDDBLQUOTE/"/g;
291 $values->{$k} = $v;
292 }
293
294 return ( $measurement, $values, $tags, $timestamp );
295}
296
29714µs1;
298
299__END__
 
# spent 1µs within InfluxDB::LineProtocol::CORE:match which was called: # once (1µs+0s) by InfluxDB::LineProtocol::import at line 27
sub InfluxDB::LineProtocol::CORE:match; # opcode