File Coverage

blib/lib/Audio/Nama/Log.pm
Criterion Covered Total %
statement 44 60 73.3
branch 8 18 44.4
condition 2 13 15.3
subroutine 9 12 75.0
pod 0 6 0.0
total 63 109 57.8


line stmt bran cond sub pod time code
1             # ----------- Logging ------------
2              
3             package Audio::Nama::Log;
4 5     5   764 use Modern::Perl;
  5         12958  
  5         35  
5 5     5   5790 use Log::Log4perl qw(get_logger :levels);
  5         215009  
  5         32  
6 5     5   612 use Exporter;
  5         10  
  5         198  
7 5     5   22 use Carp qw(carp cluck confess croak);
  5         28  
  5         3285  
8             our @ISA = 'Exporter';
9             our @EXPORT_OK = qw(logit loggit logpkg logsub initialize_logger);
10             our $appender;
11              
12             sub initialize_logger {
13 1     1 0 5 my $cat_string = shift;
14              
15 1         12 my @all_cats = qw(
16             Audio::Nama::AnalyseLV2
17             Audio::Nama::Assign
18             Audio::Nama::Bunch
19             Audio::Nama::Bus
20             Audio::Nama::CacheTrack
21             Audio::Nama::ChainSetup
22             Audio::Nama::Config
23             Audio::Nama::Custom
24             Audio::Nama::Edit
25             Audio::Nama::EffectChain
26             Audio::Nama::Effect
27             Audio::Nama::EffectsRegistry
28             Audio::Nama::EngineCleanup
29             Audio::Nama::Engine
30             Audio::Nama::EngineRun
31             Audio::Nama::EngineSetup
32             Audio::Nama::Fade
33             Audio::Nama::Git
34             Audio::Nama::Globals
35             Audio::Nama::Grammar
36             Audio::Nama::Graphical
37             Audio::Nama::Graph
38             Audio::Nama::Help
39             Audio::Nama::Initializations
40             Audio::Nama::Insert
41             Audio::Nama::IO
42             Audio::Nama::Jack
43             Audio::Nama::Latency
44             Audio::Nama::Lat
45             Audio::Nama::Log
46             Audio::Nama::Mark
47             Audio::Nama::Memoize
48             Audio::Nama::Midi
49             Audio::Nama::Mix
50             Audio::Nama::Modes
51             Audio::Nama::MuteSoloFade
52             Audio::Nama::Nama
53             Audio::Nama::Object
54             Audio::Nama::Options
55             Audio::Nama::Persistence
56             Audio::Nama::Plug
57             Audio::Nama::Project
58             Audio::Nama::RegionComp
59             Audio::Nama::Regions
60             Audio::Nama::Sequence
61             Audio::Nama::Terminal
62             Audio::Nama::Text
63             Audio::Nama::Track
64             Audio::Nama::Util
65             Audio::Nama::Wavinfo
66             Audio::Nama::Wav
67              
68             );
69 1         2 push @all_cats, 'ECI','SUB';
70              
71 1         2 my %negate;
72 1 50       4 %negate = map{ $_ => 1} map{ s/^#//; $_ } grep{ /^#/ }
  0         0  
  0         0  
  0         0  
  0         0  
73             expand_cats(split q(,), $cat_string) if $cat_string;
74             #say("negate\n",Audio::Nama::json_out(\%negate));
75              
76 1         2 my $layout = "[\%r] %c %m%n"; # backslash to protect from source filter
77 1         2 my $logfile = $ENV{NAMA_LOGFILE};
78 1 50   0   3 $SIG{ __DIE__ } = sub { Carp::confess( @_ ) } if $cat_string;
  0         0  
79            
80 1 50       4 $appender = $logfile ? 'FILE' : 'STDERR';
81 1   50     8 $logfile //= "/dev/null";
82              
83 1         2 my @cats;
84 1 50       3 @cats = expand_cats(split ',', $cat_string) if $cat_string;
85             #logpkg(__FILE__,__LINE__,'debug',"initial logging categories: @cats");
86             #logpkg(__FILE__,__LINE__,'trace',"all cats: @all_cats");
87            
88 1 50       3 @cats = grep{ ! $negate{$_} } @all_cats if grep {$_ eq 'ALL'} @cats;
  0         0  
  0         0  
89            
90             #logpkg(__FILE__,__LINE__,'debug',"Final logging categories: @cats");
91              
92 1         7 my $conf = qq(
93             #log4perl.rootLogger = DEBUG, $appender
94             #log4perl.category.Audio.Nama = DEBUG, $appender
95              
96             # dummy entry - avoid no logger/no appender warnings
97             log4perl.category.DUMMY = DEBUG, DUMMY
98             log4perl.appender.DUMMY = Log::Log4perl::Appender::Screen
99             log4perl.appender.DUMMY.layout = Log::Log4perl::Layout::NoopLayout
100              
101             # screen appender
102             log4perl.appender.STDERR = Log::Log4perl::Appender::Screen
103             log4perl.appender.STDERR.layout = Log::Log4perl::Layout::PatternLayout
104             log4perl.appender.STDERR.layout.ConversionPattern = $layout
105              
106             # file appender
107             log4perl.appender.FILE = Log::Log4perl::Appender::File
108             log4perl.appender.FILE.filename = $logfile
109             log4perl.appender.FILE.layout = Log::Log4perl::Layout::PatternLayout
110             log4perl.appender.FILE.layout.ConversionPattern = $layout
111              
112             #log4perl.additivity.SUB = 0 # doesn't work... why?
113             );
114             # add lines for the categories we want to log
115 1 50       3 $conf .= join "\n", "", map{ cat_line($_)} @cats if @cats;
  0         0  
116             #say $conf;
117 1         6 Log::Log4perl::init(\$conf);
118 1         4582 return( { map { $_, 1 } @cats } )
  0         0  
119             }
120 0     0 0 0 sub cat_line { "log4perl.category.$_[0] = DEBUG, $appender" }
121              
122             sub expand_cats {
123             # Convert Module -> Audio::Nama::Module -> Audio::Nama::Module
124             # Convert !Module -> !Audio::Nama::Module -> !Audio::Nama::Module
125 5     5   29 no warnings 'uninitialized';
  5         10  
  5         2665  
126 0     0 0 0 my @cats = @_;
127 0         0 map { s/^(#)?::/$1Audio::Nama::/; $_} # SKIP_PREPROC
  0         0  
128 0 0 0     0 map { s/^(#)?/$1::/ unless /^::/ or /^#?ECI/ or /^#?SUB/ or /^ALL$/; $_ }# SKIP_PREPROC
  0   0     0  
  0   0     0  
129             @cats;
130             }
131             {
132             my %is_method = map { $_ => 1 }
133             qw( trace debug info warn error fatal
134             logwarn logdie
135             logcarp logcroak logcluck logconfess);
136            
137             sub logit {
138 100     100 0 217 my ($line_number, $category, $level, @message) = @_;
139             #say qq($line_number, $category, $level, @message) ;
140             #confess("first call to logit");
141 100 50       241 my $line_number_output = $line_number ? " (L $line_number) ": "";
142 100 50       217 cluck "illegal level: $level" unless $is_method{$level};
143 100         233 my $logger = get_logger($category);
144 100         2772 $logger->$level($line_number_output, @message);
145             }
146             }
147 10     10 0 25 sub logsub { logit(__LINE__,'SUB','debug',$_[0]) }
148              
149             *loggit = \&logit; # to avoid source filter on logit call below
150              
151             sub logpkg {
152 90     90 0 177 my( $file, $line_no, $level, @message) = @_;
153             # convert Effects.pm to Audio::Nama::Effects to support logpkg
154 90         124 my $pkg = $file;
155 90         638 ($pkg) = $file =~ m| ([^/]+)\.pm$ |x;
156 90   50     194 $pkg //= "Dummy::Pkg";
157 90         159 $pkg = "Audio::Nama::$pkg"; # SKIP_PREPROC
158             #say "category: $pkg";
159 90         177 logit ($line_no,$pkg,$level, @message)
160             }
161            
162             1;