Subversion Repositories DevTools

Rev

Rev 7389 | Rev 7397 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7387 dpurdie 1
#! /usr/bin/perl
2
########################################################################
3
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
4
#
5
# Module name   : blatTarZip.pl
6
# Module type   :
7
# Compiler(s)   : Perl
8
# Environment(s):
9
#
10
# Description   :   This is a blat related task that will monitor a
11
#                   directory for requests to tarZip a package
12
#
13
# Usage         :   ARGV[0] - Path to config file for this instance
14
#
15
#......................................................................#
16
 
17
require 5.008_002;
18
use strict;
19
use warnings;
20
use Getopt::Long;
21
use File::Basename;
22
use Data::Dumper;
23
use File::Spec::Functions;
24
use POSIX ":sys_wait_h";
25
use File::Temp qw/tempfile/;
26
use Digest::MD5;
27
 
28
use FindBin;                                    # Determine the current directory
29
use lib "$FindBin::Bin/lib";                    # Allow local libraries
30
 
31
use Utils;
32
use StdLogger;                                  # Log to sdtout
33
use Logger;                                     # Log to file
34
 
35
#
36
#   Database interface
37
#   Pinched from jats and modified so that this software is not dependent on JATS
38
#
39
use IO::Handle;
40
use JatsRmApi;
41
use DBI;
42
 
43
#
44
#   Globals
45
#
46
my $logger = StdLogger->new();                  # Stdout logger. Only during config
47
$logger->err("No config file specified") unless (defined $ARGV[0]);
48
$logger->err("Config File does not exist: $ARGV[0]") unless (-f $ARGV[0]);
49
my $name = basename( $ARGV[0]);
50
   $name =~ s~.conf$~~;
51
my $now = 0;
52
my $startTime = 0;
53
my $tagDirTime = 0;
54
my $lastDirScan = 0;
55
my $lastCleanScan =  0;
56
my $mtimeConfig = 0;
57
my $conf;
58
my $yday = -1;
59
my $tagRoot;
60
 
61
#
62
#   Contain statisics maintained while operating
63
#       Can be dumped with a kill -USR2
64
#       List here for documentation
65
#  
66
 
67
my %statistics = (
68
    SeqNum => 0,                        # Bumped when $statistics are dumped
69
    timeStamp => 0,                     # DateTime when statistics are dumped
70
    upTime => 0,                        # Seconds since program start
71
    Cycle => 0,                         # Major process loop counter
72
    phase => 'Init',                    # Current phase of operation
73
    state => 'OK',                      # Nagios state
74
                                        # 
75
                                        # The following are reset each day
76
    dayStart => 0,                      # DateTime when daily data was reset
77
    txCount => 0,                       # Packages Transferred
78
    delCount => 0,                      # Packages marked for deletion
79
    staleTags => 0,                     # Stale Tags
80
    linkErrors => 0,                    # Transfer (zip) errors
81
                                        # 
82
                                        # Per Cycle Data - Calculated each processing Cycle
83
    total    => 0,                      # Packages to be synced
84
    delete   => 0,                      # Packages to delete
85
    excluded => 0,                      # Packages excluded    
86
    filtered => 0,                      # Packages filtered out
87
    missing  => 0,                      # Packages missing
88
    transfer => 0,                      # Packages to transfer
89
    writable => 0,                      # Packages still writable - thus not transferred
90
    tagCount => 0,                      # Packages tagged to be transferred
91
                                        #
92
);
93
 
94
#
95
#   Describe configuration parameters
96
#
97
my %cdata = (
98
    'piddir'          => {'mandatory' => 1      , 'fmt' => 'dir'},
99
    'sleep'           => {'default'   => 5      , 'fmt' => 'period'},
100
    'dpkg_archive'    => {'mandatory' => 1      , 'fmt' => 'dir'},
101
    'logfile'         => {'mandatory' => 1      , 'fmt' => 'vfile'},
102
    'logfile.size'    => {'default'   => '1M'   , 'fmt' => 'size'},
103
    'logfile.count'   => {'default'   => 9      , 'fmt' => 'int'},
104
    'verbose'         => {'default'   => 0      , 'fmt' => 'int'},
105
    'active'          => {'default'   => 1      , 'fmt' => 'bool'},
106
    'debug'           => {'default'   => 0      , 'fmt' => 'bool'},                 # Log to screen
107
    'tagdir'          => {'mandatory' => 1      , 'fmt' => 'dir'},
108
    'forcedirscan'    => {'default'   => 100    , 'fmt' => 'period'},
109
    'tagMaxPackages'  => {'default'   => 10     , 'fmt' => 'int'},
110
    'tagage'          => {'default'   => '10d'  , 'fmt' => 'period'},
111
    'cleanPeriod'     => {'default'   => '30m'  , 'fmt' => 'period'},
7389 dpurdie 112
    'maxFileAge'      => {'default'   => '24h'  , 'fmt' => 'period'},
113
    'txdetail'        => {'default'   => 0      , 'fmt' => 'bool'},
7387 dpurdie 114
 
115
 
116
);
117
 
118
 
119
#
120
#   Read in the configuration
121
#       Set up a logger
122
#       Write a pidfile - thats not used
123
$now = $startTime = time();
124
readConfig();
125
Utils::writepid($conf);
126
$logger->logmsg("Starting...");
127
readStatistics();
128
sighandlers($conf);
129
 
130
#
131
#   Main processing loop
132
#   Will exit when terminated by parent
133
#
134
while (1)
135
{
136
    $logger->verbose3("Processing");
137
    $statistics{Cycle}++;
138
    $now = time();
139
 
140
    $statistics{phase} = 'ReadConfig';
141
    readConfig();
142
    if ( $conf->{'active'} )
143
    {
144
        $statistics{phase} = 'Monitor Tags';
145
        processRequests();
146
        cleanZipStore();
147
    }
148
 
149
    $statistics{phase} = 'Sleep';
150
    sleep( $conf->{'sleep'} );
151
    reapChildren();
152
 
153
    #   If my PID file ceases to be, then exit the daemon
154
    #   Used to force daemon to restart
155
    #
156
    unless ( -f $conf->{'pidfile'} )
157
    {
158
        $logger->logmsg("Terminate. Pid file removed");
159
        last;
160
    }
161
}
162
$statistics{phase} = 'Terminated';
163
$logger->logmsg("Child End");
164
exit 0;
165
 
166
#-------------------------------------------------------------------------------
167
# Function        : reapChildren 
168
#
169
# Description     : Reap any and all dead children
170
#                   Call in major loops to prevent zombies accumulating 
171
#
172
# Inputs          : None
173
#
174
# Returns         : 
175
#
176
sub reapChildren
177
{
178
    my $currentPhase = $statistics{phase};
179
    $statistics{phase} = 'Reaping';
180
 
181
    my $kid;
182
    do {
183
        $kid = waitpid(-1, WNOHANG);
184
    } while ( $kid > 0 );
185
 
186
    $statistics{phase} = $currentPhase;
187
}
188
 
189
 
190
#-------------------------------------------------------------------------------
191
# Function        : readConfig
192
#
193
# Description     : Re read the config file if it modification time has changed
194
#
195
# Inputs          : Nothing
196
#
197
# Returns         : 0       - Config not read
198
#                   1       - Config read
199
#                             Config file has changed
200
#
201
sub readConfig
202
{
203
    my ($mtime) = Utils::mtime($ARGV[0]);
204
    my $rv = 0;
205
 
206
    if ( $mtimeConfig != $mtime )
207
    {
208
        $logger->logmsg("Reading config file: $ARGV[0]");
209
        $mtimeConfig = $mtime;
210
        my $errors;
211
        ($conf, $errors) = Utils::readconf ( $ARGV[0], \%cdata );
212
        if ( scalar @{$errors} > 0 )
213
        {
214
            warn "$_\n" foreach (@{$errors});
215
            die ("Config contained errors\n");
216
        }
217
 
218
        #
219
        #   Reset some information
220
        #   Create a new logger
221
        #
222
        $logger = Logger->new($conf) unless $conf->{debug};
223
        $conf->{logger} = $logger;
224
        $conf->{'pidfile'} = $conf->{'piddir'} . '/' . $name . '.pid';
225
        $logger->setVerbose($conf->{verbose});
226
        $logger->verbose("Log Levl: $conf->{verbose}");
227
 
228
        #
229
        #   Setup statistics filename
230
        $conf->{'statsfile'} = $conf->{'piddir'} . '/' . $name . '.stats';
231
        $conf->{'statsfiletmp'} = $conf->{'piddir'} . '/' . $name . '.stats.tmp';
232
 
233
        #
234
        #   Calculate the base of the tags directory
235
        #   ASSUME all tagdirs are in the same tree as my tags dir
236
        #
237
        $conf->{'tagdir'} =~ m~^(.*)/~;
238
        $tagRoot = $1;
239
    }
240
 
241
    #
242
    #   When config is read force some actions
243
 
244
#Utils::DebugDumpData ("Config", $conf);
245
 
246
    $logger->warn("Tar Zip is inactive") unless ( $conf->{'active'} );
247
    return $rv;
248
}
249
 
250
 
251
#-------------------------------------------------------------------------------
252
# Function        : processRequests
253
#
254
# Description     : Process tags and generate tarZip files as required
255
#                       Determine if new tags are present
256
#                       Process each tag
257
#
258
# Inputs          : None
259
#
260
# Returns         : Nothing
261
#
262
sub processRequests
263
{
264
    #
265
    #   Determine if new tags are present by examining the time
266
    #   that the directory was last modified.
267
    #
268
    #   Allow for a forced scan to catch packages that did not transfer
269
    #   on the first attempt
270
    #
271
    my $tagCount = 0;
272
    my ($mtime) = Utils::mtime($conf->{'tagdir'} );
273
    if ( ($mtime > $tagDirTime) || ($now > ($lastDirScan + $conf->{'forcedirscan'})) )
274
    {
275
        $logger->verbose2("processTags: ,$conf->{'tagdir'}");
276
        $tagDirTime = $mtime;
277
        $lastDirScan = $now;
278
        my $txcount = $conf->{'tagMaxPackages'};
279
 
280
 
281
        my $dh;
282
        unless (opendir($dh, $conf->{'tagdir'}))
283
        {
284
            $logger->warn ("can't opendir $conf->{'tagdir'}: $!");
285
            return;
286
        }
287
 
288
        #
289
        #   Process each entry
290
        #   Ignore those that start with a .
291
        #
292
        my %tagPkgList;
293
        while (my $tag = readdir($dh) )
294
        {
295
            next if ( $tag =~ m~^\.~ );
296
            my $file = "$conf->{'tagdir'}/$tag";
297
            $logger->verbose3("processTags: $file");
298
 
299
            if ( $tag =~ m~(.+)::(.+)~  )
300
            {
301
                my $package = $1;
302
                my $version = $2;
303
                $tagCount++;
304
                $tagPkgList{$package}{$version} = $file;
305
            }
306
        }
307
        $statistics{tagCount} = $tagCount;
308
        closedir $dh;
309
 
310
        #
311
        #   Process the packages located in the tags area
312
        #
313
        send_tags:
314
        while ( (my ($package, $pvers)) = each %{tagPkgList} )
315
        {
316
            while ( (my ($version, $file) ) = each %{$pvers} )
317
            {
318
                if ( --$txcount <= 0 )
319
                {
320
                    $logger->warn("Max tag transfer count exceeded: $tagCount transfer remaining");
321
                    $tagDirTime = 0;
322
                    last send_tags;
323
                }
324
 
325
                if ( readConfig() )
326
                {
327
                    $logger->warn("Config file changed");
328
                    $txcount = 0;
329
                    $tagDirTime = 0;
330
                    last send_tags;
331
                }
332
 
333
                #
334
                #
7394 dpurdie 335
                if ( ! zipRequestNeeded($package, $version) ) {
336
                    $logger->verbose2("NoZip request outstanding: $package, $version");
7387 dpurdie 337
                    unlink $file;
7394 dpurdie 338
 
339
                } elsif ( tarZipPackage( $package, $version )) {
340
                    unlink $file;
7387 dpurdie 341
                    triggerTransfers($package, $version);
342
                }
343
                else
344
                {
345
                    if ($conf->{'tagage'} > 0) {
346
                        my ($mtime) = Utils::mtime( $file );
347
                        if ( $now - $mtime > $conf->{'tagage'} )
348
                        {
349
                            $logger->warn ("Delete unsatisfied tag: $package::$version after $conf->{'tagage'}" );
350
                            unlink $file;
351
                            $statistics{staleTags}++;
352
                        }
353
                    }
354
                }
355
 
356
                $tagCount--;
357
                reapChildren();
358
            }
359
        }
360
    }
361
}
362
 
363
#-------------------------------------------------------------------------------
7394 dpurdie 364
# Function        : zipRequestNeeded 
365
#
366
# Description     : Scan tags and ensure that the zip request is still needed
367
#                   Another task must still have need for this package to be
368
#                   tarZipped
369
#
370
# Inputs          : $pname
371
#                   $version 
372
#
373
# Returns         : True if still needed 
374
#
375
sub zipRequestNeeded {
376
    my ($pname, $version) = @_;
377
 
378
    #
379
    #   Find the tag in all blat transfer areas
380
    #   
381
    my $tag = "$pname::$version";
382
    my @tagList = glob ("$tagRoot/*/$tag");
383
 
384
    #
385
    #   Expect to find my own tag, so a count of 1 indicates not found elsewhere
386
    # 
387
    my $count = scalar @tagList;
388
    return $count > 1;   
389
}
390
 
391
 
392
#-------------------------------------------------------------------------------
7387 dpurdie 393
# Function        : cleanZipStore  
394
#
395
# Description     : Cleanup the store of zipped packages
396
#                   If a tarZip is no longer needed for a transfer, then we can consider
397
#                   removing it from the store
398
#                   
399
#                   May want to keep it for some time, but ...
400
#                   
401
#                   May need to remove them if they are too old.
402
#                   When a connection is wedged, then we may end up with a lot of packages
403
#                   May be that the ssh tx process will age out old tags, but I don't think so 
404
#                   
405
#                   Should be run periodically
406
#
407
# Inputs          : 
408
#
409
# Returns         : 
410
#
411
sub cleanZipStore
412
{
413
    if ( $conf->{cleanPeriod} == 0 )
414
    {
415
        $logger->verbose2("cleanZipStore disabled");
416
        return;
417
    }
418
 
419
    #
420
    #   Time to perform the scan
421
    #   Will do at startup and every time period there after
422
    #
423
    return unless ( $now > ($lastCleanScan + $conf->{cleanPeriod} ));
424
    $logger->verbose("cleanZipStore");
425
    $lastCleanScan = $now;
426
 
427
 
428
    my %tagPkgList;
429
    #
430
    #   Locate all the tags and create a hash of known tags
431
    #   These are packages that we have queued to be transferred
432
    #
433
    my @tagList = glob ("$tagRoot/*/*::*");
434
 
435
    foreach my $entry ( @tagList )
436
    {
437
        $entry =~ m~.*/(.*)::(.*)$~;
438
        $tagPkgList{$1 .'__'.$2 . '.tgz'} = 1;
439
    }
440
 
441
    #
442
    #   Iterate over all the stored tarZips and remove them if they are no longer needed
443
    #
444
    my @tarZipFiles = glob (catfile( $conf->{'dpkg_archive'}, '.dpkg_archive', 'tarStore', '*.tgz' ));
445
    foreach my $entry  (@tarZipFiles) {
446
        $entry =~ m~.*/(.*)$~;
447
        my $fname = $1;
448
 
449
        if (!exists $tagPkgList{$fname}) {
7389 dpurdie 450
 
451
            my ($mtime) = Utils::mtime($entry);
452
            my $age = time() - $mtime;
453
            $logger->verbose3( "File Age: $age, $conf->{maxFileAge}");
454
            if ( $age > $conf->{maxFileAge} ) {
455
                $logger->logmsg("cleanZipStore. Remove: $fname");
456
                unlink $entry;
457
                $logger->warn("cleanZipStore. Cannot Remove: $fname") if (-f $entry);
458
            }
7387 dpurdie 459
        } else {
460
            $logger->verbose("cleanZipStore. Retain: $fname");
461
 
462
        }
463
    }
464
 
465
}
466
 
467
 
468
#-------------------------------------------------------------------------------
469
# Function        : tarZipPackage 
470
#
471
# Description     : Perform the tar Zip operation 
472
#
473
# Inputs          : $pname
474
#                   $version 
475
#
476
# Returns         : 1 - TarZip complete
477
#                   0 - TarZip not complete 
478
#
479
sub tarZipPackage
480
{
481
    my ($pname, $version) = @_;
482
    $logger->logmsg("TarZip $pname $version");
483
 
484
    my $pkgName = $pname .'_'.$version;
485
    my $srcDir = catdir( $conf->{'dpkg_archive'}, $pname, $version);
486
    my $tgtdir = catfile( $conf->{'dpkg_archive'}, '.dpkg_archive', 'tarStore' );
487
    my $zfile = $pname . '__' . $version . '.tgz';
488
    my $tfile = catfile($tgtdir, $zfile);
489
    my $tfileTmp = $tfile . '.TEMP';
7389 dpurdie 490
    my $startTime = time;
7387 dpurdie 491
 
492
    #
493
    #   Does the source exist
494
    if (! -d $srcDir) {
495
        $logger->warn("Package not found: $pname, $version");
496
        return 0;
497
    }
498
 
499
    #
500
    #   If the target zip is already present, then assume the job has been done
501
    #   
502
    if ( -f $tfile ) {
503
        $logger->verbose("tarZipPackage: Already done: $pname, $version");
504
        $logger->verbose2("tarZipPackage: Already done: $pname, $version - $tfile");
505
        return 1;
506
    }
507
 
508
    #
509
    #   Tar zip the file
510
    #       TarZip into a temp file, then rename it
511
    #
512
    my $tar_cmd = "tar -czf $tfileTmp -C  $conf->{'dpkg_archive'} $pname/$version";
513
    $logger->verbose2("tarZipPackage:tar_cmd:$tar_cmd");
514
 
515
    my $ph;
516
    my $cmdRv;
517
    open ($ph, "$tar_cmd |");
518
    while ( <$ph> )
519
    {
520
        chomp;
521
        $logger->verbose2("tarZipPackage:Data: $_");
522
    }
523
    close ($ph);
524
    $cmdRv = $?;
525
    $logger->verbose("tarZipPackage:End: $cmdRv");
526
 
527
    #   Rename the TEMP file, so that the tgz file creation appears atomic
528
    if ($cmdRv eq 0 && -f $tfileTmp) {
529
        rename $tfileTmp, $tfile || $logger->warn("Rename error: $tfileTmp");
530
    }
531
 
7389 dpurdie 532
 
533
    #
534
    #   Display the size of the package (tarZipped)
535
    #       Diagnostic use
536
    #
537
    if ( -f $tfile && $conf->{txdetail}) {
538
        my $tzfsize = -s $tfile; 
539
        my $size = sprintf "%.3f", $tzfsize / 1024 / 1024 / 1024 ;
540
        my $duration = time - $startTime;
541
        $logger->logmsg("tarZipPackage: Stats: $pname, $version, $size Gb, $duration Secs");
542
    }
543
 
544
 
7387 dpurdie 545
    if ( -f $tfile ) {
546
        $statistics{txCount}++;
547
        $logger->verbose2("tarZipPackage:Done: $pname/$version");
548
        $cmdRv = 1;
549
    } else {
550
        unlink $tfileTmp;
551
        $statistics{linkErrors}++;
552
        $logger->verbose2("tarZipPackage:Error: $pname/$version");
553
        $cmdRv = 0;
554
    }
555
 
556
    #
557
    # Return 0 if the required tar file exists
558
    #   
559
    return $cmdRv;
560
}
561
 
562
#-------------------------------------------------------------------------------
563
# Function        : triggerTransfers 
564
#
565
# Description     : Trigger transfers for other blat tasks that may be waiting for this
566
#                   tarZip to have been performed
567
#
568
# Inputs          : $pname
569
#                   $version 
570
#
571
# Returns         : Even less 
572
#
573
sub triggerTransfers
574
{
575
    my ($pname, $version) = @_;
576
 
577
    #
578
    #   Find the tag in all blat transfer areas
579
    #   
580
    my $tag = "$pname::$version";
581
    my @tagList = glob ("$tagRoot/*/$tag");
7389 dpurdie 582
    $logger->verbose2("triggerTransfer: $tagRoot/*/$tag: @tagList");
7387 dpurdie 583
    foreach my $target ( @tagList )
584
    {
585
        $logger->verbose2("triggerTransfer: $target");
586
        $target =~ m~^(.*)/~;
587
        my $triggerFile = catfile($1, '.trigger');
588
        Utils::TouchFile($conf, $triggerFile);
589
    }
590
}
591
 
592
#-------------------------------------------------------------------------------
593
# Function        : resetDailyStatistics 
594
#
595
# Description     : Called periodically to reset the daily statistics
596
#
597
# Inputs          : $time       - Current time
598
#
599
# Returns         : 
600
#
601
sub resetDailyStatistics
602
{
603
    my ($time) = @_;
604
 
605
    #
606
    #   Detect a new day
607
    #
608
    my $today = (localtime($time))[7];
609
    if ($yday != $today)
610
    {
611
        $yday = $today;
612
        $logger->logmsg('Resetting daily statistics' );
613
 
614
        # Note: Must match @recoverTags in readStatistics
615
        $statistics{dayStart} = $time;
616
        $statistics{txCount} = 0;
617
        $statistics{delCount} = 0;
618
        $statistics{staleTags} = 0;
619
        $statistics{linkErrors} = 0;
620
    }
621
}
622
 
623
#-------------------------------------------------------------------------------
624
# Function        : readStatistics 
625
#
626
# Description     : Read in the last set of stats
627
#                   Used after a restart to recover daily statistics
628
#
629
# Inputs          : 
630
#
631
# Returns         : 
632
#
633
sub readStatistics
634
{
635
    my @recoverTags = qw(dayStart txCount delCount staleTags linkErrors);
636
 
637
    if ($conf->{'statsfile'} and -f $conf->{'statsfile'})
638
    {
639
        if (open my $fh, $conf->{'statsfile'})
640
        {
641
            while (<$fh>)
642
            {
643
                m~(.*):(.*)~;
644
                if ( grep( /^$1$/, @recoverTags ) ) 
645
                {
646
                    $statistics{$1} = $2;
647
                    $logger->verbose("readStatistics $1, $2");
648
                }
649
            }
650
            close $fh;
651
            $yday = (localtime($statistics{dayStart}))[7];
652
        }
653
    }
654
}
655
 
656
 
657
#-------------------------------------------------------------------------------
658
# Function        : periodicStatistics 
659
#
660
# Description     : Called on a regular basis to write out statistics
661
#                   Used to feed information into Nagios
662
#                   
663
#                   This function is called via an alarm and may be outside the normal
664
#                   processing loop. Don't make assumptions on the value of $now
665
#
666
# Inputs          : 
667
#
668
# Returns         : 
669
#
670
sub periodicStatistics
671
{
672
    #
673
    #   A few local stats
674
    #
675
    $statistics{SeqNum}++;
676
    $statistics{timeStamp} = time();
677
    $statistics{upTime} = $statistics{timeStamp} - $startTime;
678
 
679
    #   Reset daily accumulations - on first use each day
680
    resetDailyStatistics($statistics{timeStamp});
681
 
682
    #
683
    #   Write statistics to a file
684
    #       Write to a tmp file, then rename.
685
    #       Attempt to make the operation atomic - so that the file consumer
686
    #       doesn't get a badly formed file.
687
    #   
688
    if ($conf->{'statsfiletmp'})
689
    {
690
        my $fh;
691
        unless (open ($fh, '>', $conf->{'statsfiletmp'}))
692
        {
693
            $fh = undef;
694
            $logger->warn("Cannot create temp stats file: $!");
695
        }
696
        else
697
        {
698
            foreach my $key ( sort { lc($a) cmp lc($b) } keys %statistics)
699
            {
700
                print $fh $key . ':' . $statistics{$key} . "\n";
701
                $logger->verbose2('Statistics:'. $key . ':' . $statistics{$key});
702
            }
703
            close $fh;
704
 
705
            # Rename temp to real file
706
            rename  $conf->{'statsfiletmp'},  $conf->{'statsfile'} ;
707
        }
708
    }
709
}
710
 
711
#-------------------------------------------------------------------------------
712
# Function        : sighandlers
713
#
714
# Description     : Install signal handlers
715
#
716
# Inputs          : $conf           - System config
717
#
718
# Returns         : Nothing
719
#
720
sub sighandlers
721
{
722
    my $conf = shift;
723
    my $logger = $conf->{logger};
724
 
725
    $SIG{TERM} = sub {
726
        # On shutdown
727
        $logger->logmsg('Received SIGTERM. Shutting down....' );
728
        unlink $conf->{'pidfile'} if (-f $conf->{'pidfile'});
729
        exit 0;
730
    };
731
 
732
    $SIG{HUP} = sub {
733
        # On logrotate
734
        $logger->logmsg('Received SIGHUP.');
735
        $logger->rotatelog();
736
    };
737
 
738
    $SIG{USR1} = sub {
739
        # On Force Cache Clean
740
        $logger->logmsg('Received SIGUSR1.');
741
        $lastCleanScan = 0;
742
    };
743
 
744
    alarm 60;
745
    $SIG{ALRM} = sub {
746
        # On Dump Statistics
747
        $logger->verbose2('Received SIGUSR2.');
748
        periodicStatistics();
749
        alarm 60;
750
    };
751
 
752
    $SIG{__WARN__} = sub { $logger->warn("@_") };
753
    $SIG{__DIE__} = sub { $logger->err("@_") };
754
}
755
 
756
 
757
#-------------------------------------------------------------------------------
758
# Function        : Error, Verbose, Warning
759
#
760
# Description     : Support for JatsRmApi
761
#
762
# Inputs          : Message
763
#
764
# Returns         : Nothing
765
#
766
sub Error
767
{
768
    $logger->err("@_");
769
}
770
 
771
sub Verbose
772
{
773
    $logger->verbose2("@_");
774
}
775
 
776
sub Warning
777
{
778
    $logger->warn("@_");
779
}
780
 
781