File Coverage

blib/lib/Quote/LineProtocol.pm
Criterion Covered Total %
statement 48 56 85.7
branch 20 38 52.6
condition 3 10 30.0
subroutine 9 10 90.0
pod 4 4 100.0
total 84 118 71.1


line stmt bran cond sub pod time code
1             package Quote::LineProtocol;
2              
3 2     2   489571 use v5.26;
  2         9  
4 2     2   12 use warnings;
  2         4  
  2         143  
5 2     2   1164 use Time::Moment;
  2         3951  
  2         82  
6 2     2   43 use Scalar::Util 'blessed';
  2         14  
  2         148  
7 2     2   1318 use Syntax::Keyword::Match;
  2         11611  
  2         40  
8              
9 2     2   239 use Exporter 'import';
  2         3  
  2         4045  
10             our @EXPORT_OK = qw(measurement tags fields timestamp);
11              
12             our $VERSION = "0.1.4";
13             our $TELEGRAF = $ENV{QUOTE_TELEGRAF} // 0; # Telegraf requires special quoting
14              
15             my $qr = qr{([,=\s])}; # Match tag and field keys, and tag values
16             my $qs = $TELEGRAF ? qr{(["\\,=])} : qr{(["\\,=\s])}; # Match field string values
17              
18             sub measurement {
19 4     4 1 307491 my $str = shift;
20 4         55 return $str =~ s{([,\s])}{\Q$1\E}gr;
21             }
22              
23             sub tags {
24 7     7 1 29 my (%tags) = @_;
25 7         8 my @r;
26              
27 7         20 for my $key (keys %tags) {
28 7         12 my $val = $tags{$key};
29 7 50       20 $val = "$val" if blessed($val);
30 7 50       15 next if $val eq '';
31 7         101 push @r, sprintf(qq(%s=%s), $key =~ s{$qr}{\Q$1\E}gr, $val =~ s{$qr}{\Q$1\E}gr);
32             }
33              
34 7         42 return join ',', @r;
35             }
36              
37             sub fields {
38 10     10 1 28 my (%fields) = @_;
39 10         12 my @r;
40              
41 10         37 for my $key (sort keys %fields) {
42 10         12 my $val = $fields{$key};
43 10 50       24 $val = "$val" if blessed($val);
44 10 50       20 next if $val eq '';
45 10         10 my $type;
46              
47 10 100       18 if(ref $val) {
48 5 50 33     51 die "Type missing or invalid for field '$key'" unless exists $val->{type} && $val->{type} =~ /^[fisbu]\z/;
49 5         6 $type = $val->{type};
50 5         7 $val = $val->{value};
51 5 50 66     15 die "Type is UInt but value is negative, '$key' = '$val'" if $type eq 'u' && $val < 0;
52             }
53             else {
54             match($val : =~) {
55             case(/^-?[0-9]+\.[0-9]+$/) {
56 0         0 $type = 'f';
57             }
58             case(/^-?[0-9]+$/) {
59 0         0 $type = 'i';
60             }
61 5 50       45 case(/\w+/) {
    50          
    50          
62 5         7 $type = 's';
63             }
64             }
65             }
66              
67             match($type : eq) {
68             case('f') {
69 1         13 push @r, sprintf(qq(%s=%s), $key =~ s{$qr}{\Q$1\E}gr, $val);
70             }
71             case('i') {
72 1         9 push @r, sprintf(qq(%s=%di), $key =~ s{$qr}{\Q$1\E}gr, $val);
73             }
74             case('u') {
75 1         9 push @r, sprintf(qq(%s=%du), $key =~ s{$qr}{\Q$1\E}gr, $val);
76             }
77             case('s') {
78 6         74 push @r, sprintf(qq)%s="%s"), $key =~ s{$qr}{\Q$1\E}gr, $val =~ s{$qs}{\Q$1\E}gr);
79             }
80             case('b') {
81 1         7 push @r, sprintf(qq(%s=%s), $key =~ s{$qr}{\Q$1\E}gr, $val);
82             }
83 10 100       69 default {
    100          
    100          
    100          
    50          
84 0         0 push @r, sprintf(qq(%s="%s"), $key =~ s{$qr}{\Q$1\E}gr, $val =~ s{$qs}{\Q$1\E}gr);
85             }
86             }
87             }
88              
89 10         70 return join ',', @r;
90             }
91              
92             sub timestamp {
93 0     0 1   my ($unit, $utc) = @_;
94 0   0       $utc //= 0;
95 0   0       $unit //= '';
96 0 0         my $now = $utc ? Time::Moment->now_utc : Time::Moment->now;
97 0 0         return sprintf("%d", sprintf("%d%d", $now->epoch, $unit eq 'ns' ? $now->nanosecond
    0          
    0          
98             : $unit eq 'us' ? $now->microsecond
99             : $unit eq 'ms' ? $now->millisecond
100             : $now->nanosecond));
101             }
102              
103             1;
104             __END__