File Coverage

blib/lib/MojoX/Logite.pm
Criterion Covered Total %
statement 61 68 89.7
branch 15 24 62.5
condition 4 9 44.4
subroutine 13 14 92.8
pod 5 5 100.0
total 98 120 81.6


line stmt bran cond sub pod time code
1             package MojoX::Logite;
2              
3 3     3   49048 use strict;
  3         9  
  3         138  
4 3     3   17 use warnings;
  3         4  
  3         84  
5              
6 3     3   19 use Carp 'croak';
  3         9  
  3         382  
7              
8 3     3   17 use base 'Mojo::Log';
  3         6  
  3         5736  
9              
10 3     3   192331 use Mojo::Util qw (camelize);
  3         11  
  3         1569  
11              
12             our $VERSION = '0.01';
13              
14             our $LOG_TABLE = 'LogiteTable';
15             our $LOG_IDX1 = $LOG_TABLE.'Idx1';
16             our $LOG_IDX2 = $LOG_TABLE.'Idx2';
17             our $LOG_SCHEMA = <
18             CREATE TABLE $LOG_TABLE (
19             l_id INTEGER UNIQUE PRIMARY KEY AUTOINCREMENT,
20             l_who_app TEXT DEFAULT NULL,
21             l_who_mod TEXT DEFAULT NULL,
22             l_who_pos TEXT DEFAULT NULL,
23             l_who_id TEXT DEFAULT NULL,
24             l_what TEXT DEFAULT NULL,
25             l_when INTEGER NOT NULL,
26             l_level CHAR(10) DEFAULT NULL
27             );
28             CREATE INDEX IF NOT EXISTS $LOG_IDX1 ON $LOG_TABLE (l_when);
29             CREATE INDEX IF NOT EXISTS $LOG_IDX2 ON $LOG_TABLE (l_level,l_who_app,l_who_mod);
30             SCHEMA
31              
32             # some ORLite attributes
33             __PACKAGE__->attr('package' => 'MojoX::Logite');
34             __PACKAGE__->attr('prune' => 0);
35             __PACKAGE__->attr('user_version');
36             __PACKAGE__->attr('cache');
37             __PACKAGE__->attr('readonly');
38              
39             __PACKAGE__->attr('app');
40              
41             __PACKAGE__->attr('context_stack' => sub { [] });
42             __PACKAGE__->attr('context_map' => sub { {} });
43              
44             sub new
45             {
46 3     3 1 14190 my $class = shift;
47              
48 3         125 my $self = $class->SUPER::new(@_);
49 3         321 bless $self, $class;
50              
51             # ORLite dynamic stuff
52 3         5093 require ORLite;
53             my %orlite_options = (
54             file => $self->path,
55             package => $self->package,
56             cleanup => 'VACUUM',
57             create => sub {
58 3     3   7158 my $dbh = shift;
59 3         26 $dbh->do($LOG_SCHEMA);
60             },
61 3         156147 tables => [ $LOG_TABLE ],
62             prune => $self->prune,
63             );
64              
65 3 50       470 if ($self->user_version)
66             {
67 0         0 $orlite_options{ user_version } = $self->user_version;
68 0         0 my $pkg = $self->package;
69 3     3   24 no strict 'refs';
  3         10  
  3         3014  
70 0         0 ${"$pkg\::VERSION"} = $self->user_version;
  0         0  
71             }
72 3 50       96 $orlite_options{ cache } = $self->cache
73             if ($self->cache);
74              
75 3         46 ORLite->import( \%orlite_options );
76              
77 3         344288 return $self;
78             }
79              
80             sub package_table
81             {
82 29     29 1 10224 my ($self) = @_;
83              
84 29         1004 return $self->package.'::'.camelize($LOG_TABLE);
85             }
86              
87             sub schema
88             {
89 0     0 1 0 my ($self) = @_;
90              
91 0         0 return $LOG_SCHEMA;
92             }
93              
94             # override log method
95             sub log
96             {
97 15     15 1 196346 my ($self, $level, @msgs) = @_;
98              
99             # Check log level
100 15         53 $level = lc $level;
101 15 50 33     187 return $self unless $level && $self->is_level($level);
102              
103 15         950 my $timestamp = time; # time in milliseconds
104 15 50       116 my $msgs = join "\n",
105 15         50 map { utf8::decode $_ unless utf8::is_utf8 $_;
106 15         71 $self->_placeholders($_); } @msgs;
107              
108             # Caller
109 15         84 my ($pkg, $line) = (caller())[0, 2];
110 15 100 66     240 ($pkg, $line) = (caller(1))[0, 2] if $pkg eq ref $self or $pkg =~ m/Mojo::Log/;
111              
112 15         505 my %log_message = (
113             'l_who_mod' => $pkg,
114             'l_who_pos' => $line,
115             'l_who_id' => $$,
116             'l_what' => $msgs,
117             'l_when' => int($timestamp),
118             'l_level' => $level
119             );
120              
121 15 50       449 $log_message{ 'l_who_app' } = $self->app
122             if ($self->app);
123              
124             # Write
125 15         181 $self->package_table->create( %log_message );
126              
127 15         418945 return $self;
128             }
129              
130             sub clear
131             {
132 2     2 1 5324 my ($self, $numdays) = @_;
133              
134 2 50 33     41 croak qq/Not a valid number of days $numdays/
135             unless ($numdays =~ m/^\d+$/ && $numdays >= 0);
136              
137 2         11 my $package = $self->package_table;
138              
139             # Delete
140 2 50       41 if ($numdays == 0)
141             {
142 2         8 $self->package_table->truncate;
143             }
144             else
145             {
146 0         0 $self->package_table->delete('WHERE t_when ts < strftime("%s","now", "-? day"); ', $numdays);
147             }
148              
149 2         21149 return $self;
150             }
151              
152             sub _placeholders
153             {
154 15     15   35 my ($self, $msg) = @_;
155            
156 15         72 $msg =~ s/%([xX])(?:{(.*?)})*/_replace($self, $1, $2);/gex;
  5         18  
157              
158 15         82 return $msg;
159             }
160              
161             sub _replace
162             {
163 5     5   17 my ($self, $what, $key) = @_;
164              
165 5         14 my $ret = "[undef]";
166              
167 5 100       31 if ($what eq 'x')
    50          
168             {
169 4 100       105 $ret = join " ", @{$self->context_stack}
  2         67  
170             if (defined $self->context_stack->[-1]);
171             }
172             elsif ($what eq 'X')
173             {
174 1 50       23 $ret = $self->context_map->{$key}
175             if (exists $self->context_map->{$key});
176             }
177              
178 5         114 return $ret;
179             }
180              
181             1;
182              
183             __END__