Skip to content

Instantly share code, notes, and snippets.

@johnalvero
Last active August 29, 2015 13:57
Show Gist options
  • Save johnalvero/9582469 to your computer and use it in GitHub Desktop.
Save johnalvero/9582469 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
# Ubuntu: apt-get install libanyevent-aggressiveidle-perl liblinux-inotify2-perl libnet-amazon-s3-perl
use strict;
use warnings;
use utf8;
use AnyEvent;
use Linux::Inotify2;
use File::Find;
use POSIX;
use Net::Amazon::S3;
my $watch_dir = '/var/log';
my $AWS_ACCESS_KEY_ID="";
my $AWS_SECRET_ACCESS_KEY="";
my $BUCKET = "your-bucket";
my $s3 = Net::Amazon::S3->new(
{ aws_access_key_id => $AWS_ACCESS_KEY_ID,
aws_secret_access_key => $AWS_SECRET_ACCESS_KEY,
retry => 1,
}
);
my $bucket = $s3->bucket($BUCKET);
my $PID_FILE = "/var/run/$0.pid";
# Fork this process, to run as a daemon
daemonize();
# enable autoflush to have faster logging
$|++;
# Catch kill signals
local $SIG{TERM} = sub {
if(-f $PID_FILE){
unlink($PID_FILE)
}
print("$0 daemon killed.");
exit 0;
};
local $SIG{INT} = $SIG{TERM};
my $cv = AnyEvent->condvar;
# watcher container hash
my %W;
# Create Inotify object
my $inotify = Linux::Inotify2->new()
or die "Failed to created inotify object: $!\n";
# Search for directories to watch
find({ wanted => sub { -d $_
&& create_watcher($inotify, $File::Find::name) }
}
, $watch_dir);
# Create event loop poller
my $poller = AnyEvent->io(
fh => $inotify->fileno,
poll => 'r',
cb => sub { $inotify->poll }
);
# Receive event signals (inotify signals)
$cv->recv;
#
# Subroutines
#
sub create_watcher {
my ($inotify, $dir) = @_;
my $watcher = $inotify->watch($dir, IN_CREATE | IN_CLOSE_WRITE | IN_MOVE | IN_DELETE, sub {
my $e = shift;
my $filename = $e->fullname;
# Create watcher for directory
if(-d $filename && $e->IN_CREATE) {
create_watcher($inotify, $filename);
return
}
elsif(-f $filename){
# Create Watcher for files
if($e->IN_CLOSE_WRITE){
print "IN_CLOSE_WRITE $filename\n";
#video/MP2T
#text/plain
# Upload to S3
my $remote_key = $filename;
chop substr $remote_key, 0, 1;
$bucket->add_key_filename( $remote_key, $filename, { content_type => 'video/MP2T', },) or die $s3->err . ": " . $s3->errstr;
}
elsif($e->IN_MOVED_FROM){
print "IN_MOVE_FROM $filename\n";
}
elsif($e->IN_MOVED_TO){
print "IN_MOVED_TO $filename\n";
}
elsif($e->IN_DELETE){
print "IN_DELETE $filename\n";
}
}
});
print "Watching $dir\n";
$W{$dir} = $watcher;
}
sub daemonize {
# Inspired by http://stackoverflow.com/questions/766397/how-can-i-run-a-perl-script-as-a-system-daemon-in-linux
POSIX::setsid or die "setsid: $!";
my $pid = fork ();
if ($pid < 0) {
die "fork: $!";
}
elsif ($pid) {
exit 0;
}
chdir "/";
umask 0;
foreach (0 .. (POSIX::sysconf (&POSIX::_SC_OPEN_MAX) || 1024)) {
POSIX::close $_
}
open (STDIN, "/dev/null");
open (STDOUT, ">>/tmp/log.txt");
open (STDERR, ">&STDOUT");
# Save PID to disk
open my $pid_file, '>', $PID_FILE
or die "Could not open PID file: $!\n";
print { $pid_file } "$$";
close ($pid_file);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment