|
From: Kevin G. <ke...@go...> - 2002-12-10 17:01:41
|
Erik W. Selberg wrote:
> (yes, I'm back from the dead :)
>
> I'll toss in one... it'd be nice if at least the password (if not the
> username) could be obtained from environment variables. What we do
> around here is we have a reasonably secure script that sets certain
> environment variables and give permission to use said script via sudo.
> This lets the DBAs keep their passwords under control.
Erik, wazzup?
Actually, we do almost the same thing here, but with the addition of a
module that maps the environment variable switch to dsn/username/pwd
combos, so I approached it like this,
log4j.appender.DBAppndr = xx::DBLogger
log4j.appender.DBAppndr.sqlStatement = \
insert into log4perltest ...etc.\
=============================================
package xx::DBLogger;
use base qw(Log::Log4perl::Appender::DBI);
use xx::DB;
#subclassing the DBI appender to override _init()
sub _init {
my $self = shift;
my %params = @_;
#lookup DSN, username, pwd re: ENV
$self->{dbh} = xx::DB->new->getConnection
or die $DBI::errstr;
$self->{_mine} = 1;
$self->{sth} = $self->create_statement($params{sqlStatement});
}
========================================================
What do you think of that? Any other ideas?
> Now, granted, I'm from the school whereby username / password security
> is just dumb for applications because (a) you gotta bake 'em in
> somewhere, which means when that hacker roots your box, they can find
> it,
No doubt, can you say "cat /proc/$$/environ"?
> and (b) you can never change both at the same time and therefore you
> end up just screwing yourself, but that's just me. :)
>
> -e
>
> Kevin Goess wrote:
>
>> I needed to add logging to a database, here's a proposed solution.
>>
>> Log4j has a JDBCAppender with the warning: "This version of
>> JDBCAppender is very likely to be completely replaced in the future."
>> The API is kind of different, you call append() until the buffer is
>> full, at which point the an sth is created and executed on the
>> buffer. So the API isn't interchangeable with other appenders.
>>
>> So I've implemented a DBI appender that's completely controllable from
>> the config file, looking something like this:
>>
>> log4j.category = WARN, DBAppndr
>> log4j.appender.DBAppndr = Log::Log4perl::Appender::DBI
>> log4j.appender.DBAppndr.datasource = DBI:CSV:f_dir=t/tmp
>> log4j.appender.DBAppndr.username = bobjones
>> log4j.appender.DBAppndr.password = 12345
>> log4j.appender.DBAppndr.sqlStatement = \
>> insert into log4perltest \
>> (level, message, shortmessage) \
>> values (?,?,?)
>> log4j.appender.DBAppndr.params.1 = %p
>> log4j.appender.DBAppndr.params.2 = %m
>> log4j.appender.DBAppndr.params.3 = %5.5m
>> ...
>>
>> The code is based on Log::Dispatch::DBI by Tatsuhiko Miyagawa. His
>> module gets behavior changes via subclassing, but by the time I was
>> done I had overridden everything but DESTROY, so I just dropped the
>> dependency on his module.
>>
>> Below is the only change to existing code, the module and a unit test
>> are attached. Any comments or suggestions?
>>
>>
>> ============================================================
>> --- lib/Log/Log4perl/Appender.pm 18 Nov 2002 20:03:39
>> -0000 1.17
>> +++ lib/Log/Log4perl/Appender.pm 9 Dec 2002 19:51:31 -0000
>> @@ -120,7 +120,10 @@
>> $level,
>> 3 +
>> $Log::Log4perl::caller_depth,
>> );
>> - $self->{appender}->log(%$p);
>> + $self->{appender}->log(%$p,
>> + #these are used by our Appender::DBI
>> + log4p_category => $category,
>> + log4p_level => $level,);
>>
>> return 1;
>> }
>>
>>
>>
>> ------------------------------------------------------------------------
>>
>> package Log::Log4perl::Appender::DBI;
>>
>> use Carp;
>>
>> use strict;
>> use Log::Log4perl::Layout::PatternLayout;
>>
>> use base qw(Log::Dispatch::Output);
>>
>>
>> sub new {
>> my($proto, %params) = @_;
>> my $class = ref $proto || $proto;
>>
>> my $self = bless {}, $class;
>>
>> $self->_basic_init(%params);
>> $self->_init(%params);
>>
>> #e.g.
>> #log4j.appender.DBAppndr.params.1 = %p
>> #log4j.appender.DBAppndr.params.2 = %5.5m
>> foreach my $pnum (keys %{$params{params}}){
>> $self->{bind_value_layouts}{$pnum} =
>> Log::Log4perl::Layout::PatternLayout->new(
>> {ConversionPattern => {value =>
>> $params{params}->{$pnum}}});
>>
>> }
>>
>> return $self;
>> }
>>
>>
>> sub _init {
>> my $self = shift;
>> my %params = @_;
>>
>> # set parameters
>> if ($params{dbh}) {
>> $self->{dbh} = $params{dbh};
>> } else {
>> $self->{dbh} = DBI->connect(@params{qw(datasource username
>> password)})
>> or die $DBI::errstr;
>> $self->{_mine} = 1;
>> }
>> $self->{sth} = $self->create_statement($params{sqlStatement});
>> }
>>
>> sub create_statement {
>> my ($self, $stmt) = @_;
>>
>> $stmt || die "sqlStatement not set in Log4perl::Appender::DBI";
>>
>> return $self->{dbh}->prepare($stmt);
>> }
>>
>>
>> sub log_message {
>> my $self = shift;
>> my %p = @_;
>>
>> #params is
>> # { name => \$appender_name,
>> # level => \$Log::Log4perl::Level::L4P_TO_LD{\$level},
>> # message => \$message,
>> # log4p_category => $category,
>> # log4p_level => $level,);
>> # },
>>
>> my @qmarks = ();
>>
>> foreach my $pnum (keys %{$self->{bind_value_layouts}}){
>> my $msg = $self->{bind_value_layouts}{$pnum}->render(
>> $p{message},
>> $p{log4p_category},
>> $p{log4p_level},
>> 5 + $Log::Log4perl::caller_depth, );
>>
>> push @qmarks, $msg;
>> }
>>
>> $self->{sth}->execute(@qmarks);
>> }
>>
>> sub DESTROY {
>> my $self = shift;
>> if ($self->{_mine} && $self->{dbh}) {
>> $self->{dbh}->disconnect;
>> }
>> }
>>
>>
>> 1;
>>
>> __END__
>>
>> =head1 NAME
>>
>> Log::Log4perl::Appender::DBI - implements appending to a DB
>>
>> =head1 SYNOPSIS
>>
>> $dbh->do('CREATE TABLE log4perltest (level char(9), message
>> char(128));
>>
>> my $config = <<'EOT';
>> log4j.category = WARN, DBAppndr
>> log4j.appender.DBAppndr = Log::Log4perl::Appender::DBI
>> log4j.appender.DBAppndr.datasource = DBI:CSV:f_dir=t/tmp
>> log4j.appender.DBAppndr.username = bobjones
>> log4j.appender.DBAppndr.password = 12345
>> log4j.appender.DBAppndr.sqlStatement = \
>> insert into log4perltest \
>> (level, message, shortmessage, category, millis) \
>> values (?,?,?,?,?)
>> log4j.appender.DBAppndr.params.1 = %p
>> log4j.appender.DBAppndr.params.2 = %m
>> log4j.appender.DBAppndr.params.3 = %5.5m
>> log4j.appender.DBAppndr.params.4 = %c
>> log4j.appender.DBAppndr.params.5 = %C
>> #want the pattern layout so we can avoid the \n
>> log4j.appender.DBAppndr.layout = Log::Log4perl::Layout::PatternLayout
>> log4j.appender.DBAppndr.layout.ConversionPattern = %m
>>
>> =head1 DESCRIPTION
>>
>> This is a specialized Log::Dispatch object customized to work with
>> log4perl and its abilities.
>>
>> The code is based on Log::Dispatch::DBI by Tatsuhiko Miyagawa. I was
>> going to subclass it, but after I was done overriding, there
>> wasn't anything left in the superclass!
>>
>> This is an attempted compromise between what Log::Dispatch::DBI was
>> doing and what log4j's JDBCAppender does. Since the JDBCAppender
>> docs say it "is very likely to be completely replaced in the future"
>> and since it looks like it does stuff like prepares the sth each time
>> around (bad performance?) I didn't feel too bad about straying from
>> its example. And the Log::Dispatch::DBI required subclassing
>> to change performance, where log4perl is inspired by the power
>> of the config file!
>>
>> =head1 CHANGING DBH CONNECTIONS (POOLING)
>>
>> If you want to get your dbh from some place in particular, like
>> maybe a pool, subclass and override _init() and/or create_statement(),
>> q.v.
>>
>> =head1 LIFE OF CONNECTIONS
>>
>> This module creates an sth when it starts and keeps it for the life
>> of the program. For long-running processes (e.g. mod_perl) this
>> may be a problem, your connections may go stale.
>>
>> It also holds one connection open for every appender, which might
>> be too many.
>>
>>
>> =head1 AUTHOR
>>
>> Kevin Goess <cp...@go...> December, 2002
>>
>> =head1 SEE ALSO
>>
>> L<Log::Dispatch::DBI>
>>
>> L<Log::Log4perl::JavaMap>
>>
>> L<Log::Log4perl::JavaMap::JDBCAppender>.
>>
>> =cut
>>
>>
>>
>
>
>
>
>
> -------------------------------------------------------
> This sf.net email is sponsored by:ThinkGeek
> Welcome to geek heaven.
> http://thinkgeek.com/sf
> _______________________________________________
> log4perl-devel mailing list
> log...@li...
> https://lists.sourceforge.net/lists/listinfo/log4perl-devel
--
Happy Trails . . .
Kevin M. Goess
(and Anne and Frank)
904 Carmel Ave.
Albany, CA 94706
(510) 525-5217
|