Skip to content

Commit

Permalink
Merge branch 'topic/genericity'
Browse files Browse the repository at this point in the history
  • Loading branch information
Damien Krotkine committed May 2, 2012
2 parents aa1efb6 + 88aa63d commit 649c42a
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 111 deletions.
46 changes: 20 additions & 26 deletions README
Expand Up @@ -8,12 +8,9 @@ SYNOPSIS


with qw/ with qw/
Log::Message::Structured Log::Message::Structured
Log::Message::Structured::Stringify::AsJSON
/;
# Components must be consumed seperately
with qw/
Log::Message::Structured::Component::Date Log::Message::Structured::Component::Date
Log::Message::Structured::Component::Hostname Log::Message::Structured::Component::Hostname
Log::Message::Structured::Stringify::AsJSON
/; /;


has foo => ( is => 'ro', required => 1 ); has foo => ( is => 'ro', required => 1 );
Expand Down Expand Up @@ -50,40 +47,36 @@ COMPONENTS
* Log::Message::Structured::Component::Hostname * Log::Message::Structured::Component::Hostname


ATTRIBUTES ATTRIBUTES
The basic Log::Message::Structured role provides the following read only The basic Log::Message::Structured role provides no attributes. See
attributes: available components in Log::Message::Structured::Component::* and

consume them, or create attributes yourself, to enrich your class
epochtime
The date and time on which the event occurred, as an no of seconds since
Jan 1st 1970 (i.e. the output of time())


METHODS METHODS
The only non-accessor methods provided are those composed from The only non-accessor methods provided are those composed from
MooseX::Storage related to serialization and deserialization. MooseX::Storage related to serialization and deserialization.


freeze as_string
Return the instance as a JSON string. Returns the event as a string. By default, returns an empty string.

However as the class composes stringifier roles, as_string will return
thaw the proper string representation of the event instance.
Inflate an instance of the class from a JSON string.


pack as_hash
Return the instance data as a plain data structure (hashref). Returns the event as a hash. By default, returns a HashRef with all

public attributes ( that have a getter setup ), and their values.
pack However, as the class composes modifier roles, the hash (and thus the
Inflate an instance from a plain data structure (hashref). string representation) will be changed accordingly


BUILD BUILD
An empty build method (which will be silently discarded if you have one An empty build method (which will be silently discarded if you have one
in your class) is provided, so that additional components can wrap it in your class) is provided, so that additional components can wrap it
(to farce lazy attributes to be built). (to farce lazy attributes to be built).


REQUIRED METHODS REQUIRED METHODS
stringify None.
You must implement a stringify method, or compose a stringification role
for all Log::Message::Structured events. This is so that events will OVERLOADING
always be meaningfully loggable be printing them to STDOUT or STDERR, or Log::Message::Structured overloads the stringify operator, and return
logging them in a traditional way in a file. the result of the "as_string" method.


A note about namespace::autoclean A note about namespace::autoclean
namespace::autoclean does not work correctly with roles that supply namespace::autoclean does not work correctly with roles that supply
Expand All @@ -98,7 +91,8 @@ SEE ALSO
Log::Message::Structured::Stringify::JSON Log::Message::Structured::Stringify::JSON


AUTHOR AND COPYRIGHT AUTHOR AND COPYRIGHT
Tomas Doran (t0m) "<bobtfish@bobtfish.net>". Tomas Doran (t0m) "<bobtfish@bobtfish.net>". Damien Krotkine (dams)
"<dams@cpan.org>".


LICENSE LICENSE
Licensed under the same terms as perl itself. Licensed under the same terms as perl itself.
Expand Down
64 changes: 28 additions & 36 deletions lib/Log/Message/Structured.pm
@@ -1,29 +1,26 @@
package Log::Message::Structured; package Log::Message::Structured;
use MooseX::Role::WithOverloading; use MooseX::Role::WithOverloading;
use MooseX::Storage;
use namespace::clean -except => 'meta'; use namespace::clean -except => 'meta';


our $VERSION = '0.007'; our $VERSION = '0.007';
$VERSION = eval $VERSION; $VERSION = eval $VERSION;


use overload use overload
q{""} => 'stringify', q{""} => 'as_string',
fallback => 1; fallback => 1;


with Storage('format' => 'JSON');

my $GETOPT = do { local $@; eval { require MooseX::Getopt; 1 } }; my $GETOPT = do { local $@; eval { require MooseX::Getopt; 1 } };


has epochtime => (
isa => 'Int',
is => 'ro',
default => sub { time() },
$GETOPT ? ( traits => [qw/ NoGetopt /] ) : (),
);

sub BUILD {} sub BUILD {}


sub stringify { '' } sub as_string { '' }

sub as_hash {
my ($self) = @_;
my $meta = $self->meta;
return { map { $_->has_read_method ? ($_->name, $_->get_read_method_ref->($self)) : () }
$meta->get_all_attributes };
}


1; 1;


Expand All @@ -43,12 +40,9 @@ Log::Message::Structured - Simple structured log messages
with qw/ with qw/
Log::Message::Structured Log::Message::Structured
Log::Message::Structured::Stringify::AsJSON
/;
# Components must be consumed seperately
with qw/
Log::Message::Structured::Component::Date Log::Message::Structured::Component::Date
Log::Message::Structured::Component::Hostname Log::Message::Structured::Component::Hostname
Log::Message::Structured::Stringify::AsJSON
/; /;
has foo => ( is => 'ro', required => 1 ); has foo => ( is => 'ro', required => 1 );
Expand Down Expand Up @@ -92,32 +86,28 @@ L<Log::Message::Structured::Component::Hostname>
=head1 ATTRIBUTES =head1 ATTRIBUTES
The basic Log::Message::Structured role provides the following read only attributes: The basic Log::Message::Structured role provides no attributes. See available
components in L<Log::Message::Structured::Component::*> and consume them, or
create attributes yourself, to enrich your class
=head1 epochtime
The date and time on which the event occurred, as an no of seconds since Jan 1st 1970 (i.e. the output of time())
=head1 METHODS =head1 METHODS
The only non-accessor methods provided are those composed from L<MooseX::Storage> related to serialization The only non-accessor methods provided are those composed from L<MooseX::Storage> related to serialization
and deserialization. and deserialization.
=head2 freeze =head2 as_string
Return the instance as a JSON string.
=head2 thaw
Inflate an instance of the class from a JSON string. Returns the event as a string. By default, returns an empty string. However as the
class composes stringifier roles, as_string will return the proper string
representation of the event instance.
=head2 pack =head2 as_hash
Return the instance data as a plain data structure (hashref). Returns the event as a hash. By default, returns a HashRef with all public
attributes ( that have a getter setup ), and
=head2 pack their values. However, as the class composes modifier roles, the hash (and thus
the string representation) will be changed accordingly
Inflate an instance from a plain data structure (hashref).
=head2 BUILD =head2 BUILD
Expand All @@ -127,11 +117,12 @@ in your class) is provided, so that additional components can wrap it
=head1 REQUIRED METHODS =head1 REQUIRED METHODS
=head2 stringify None.
=head1 OVERLOADING
You B<must> implement a stringify method, or compose a stringification role for all L<Log::Message::Structured> Log::Message::Structured overloads the stringify operator, and return the
events. This is so that events will always be meaningfully loggable be printing them to STDOUT or STDERR, result of the C<as_string> method.
or logging them in a traditional way in a file.
=head1 A note about namespace::autoclean =head1 A note about namespace::autoclean
Expand All @@ -154,6 +145,7 @@ instead in all classes using L<Log::Message::Structured>.
=head1 AUTHOR AND COPYRIGHT =head1 AUTHOR AND COPYRIGHT
Tomas Doran (t0m) C<< <bobtfish@bobtfish.net> >>. Tomas Doran (t0m) C<< <bobtfish@bobtfish.net> >>.
Damien Krotkine (dams) C<< <dams@cpan.org> >>.
=head1 LICENSE =head1 LICENSE
Expand Down
26 changes: 16 additions & 10 deletions lib/Log/Message/Structured/Component/Date.pm
Expand Up @@ -7,6 +7,13 @@ use MooseX::Types::ISO8601 qw/ ISO8601DateTimeStr /;


my $GETOPT = do { local $@; eval { require MooseX::Getopt; 1 } }; my $GETOPT = do { local $@; eval { require MooseX::Getopt; 1 } };


has epochtime => (
isa => 'Int',
is => 'ro',
default => sub { time() },
$GETOPT ? ( traits => [qw/ NoGetopt /] ) : (),
);

has date => ( has date => (
is => 'ro', is => 'ro',
isa => ISO8601DateTimeStr, isa => ISO8601DateTimeStr,
Expand All @@ -18,8 +25,6 @@ has date => (


after BUILD => sub { shift()->date }; after BUILD => sub { shift()->date };


requires 'epochtime';

1; 1;


__END__ __END__
Expand All @@ -38,9 +43,6 @@ Log::Message::Structured::Component::Date
with qw/ with qw/
Log::Message::Structured Log::Message::Structured
/;
# Components must be consumed seperately
with qw/
Log::Message::Structured::Component::Date Log::Message::Structured::Component::Date
/; /;
Expand All @@ -56,10 +58,8 @@ Log::Message::Structured::Component::Date
=head1 DESCRIPTION =head1 DESCRIPTION
Provides a C<'date'> attribute to the consuming class ( probably Provides C<'epochtime'> and C<'date'> attributes to the consuming class ( that should also
L<Log::Message::Structured>), representing the epoch time in ISO8601. consume L<Log::Message::Structured>).
Requires the C<epochtime> attribute (L<Log::Message::Structured> provides it).
=head1 METHODS =head1 METHODS
Expand All @@ -70,12 +70,18 @@ construction time.
=head1 ATTRIBUTES =head1 ATTRIBUTES
=head1 date =head2 date
The date and time on which the event occured, as an ISO8601 date time string The date and time on which the event occured, as an ISO8601 date time string
(from L<MooseX::Types::ISO8601>). Defaults to the time the object is (from L<MooseX::Types::ISO8601>). Defaults to the time the object is
constructed. constructed.
=head2 epochtime
The date and time on which the event occurred, as an no of seconds since Jan
1st 1970 (i.e. the output of time()). Defaults to the time the object is
constructed.
=head1 AUTHOR AND COPYRIGHT =head1 AUTHOR AND COPYRIGHT
Damien Krotkine (dams) C<< <dams@cpan.org> >>. Damien Krotkine (dams) C<< <dams@cpan.org> >>.
Expand Down
3 changes: 0 additions & 3 deletions lib/Log/Message/Structured/Component/Hostname.pm
Expand Up @@ -30,9 +30,6 @@ Log::Message::Structured::Component::Hostname
with qw/ with qw/
Log::Message::Structured Log::Message::Structured
/;
# Components must be consumed seperately
with qw/
Log::Message::Structured::Component::Hostname Log::Message::Structured::Component::Hostname
/; /;
Expand Down
4 changes: 2 additions & 2 deletions lib/Log/Message/Structured/Event/ScriptRun.pm
Expand Up @@ -18,8 +18,8 @@ has time => (


# FIXME - User running script? # FIXME - User running script?


with qw( Log::Message::Structured ); with qw( Log::Message::Structured
with qw( Log::Message::Structured::Component::Date Log::Message::Structured::Component::Date
Log::Message::Structured::Component::Hostname Log::Message::Structured::Component::Hostname
); );
with 'Log::Message::Structured::Stringify::Sprintf' => { with 'Log::Message::Structured::Stringify::Sprintf' => {
Expand Down
22 changes: 14 additions & 8 deletions lib/Log/Message/Structured/Stringify/AsJSON.pm
Expand Up @@ -2,15 +2,20 @@ package Log::Message::Structured::Stringify::AsJSON;
use Moose::Role; use Moose::Role;
use namespace::autoclean; use namespace::autoclean;


requires 'freeze'; use JSON::Any;
use utf8 ();


around 'stringify' => sub { requires 'as_hash';

around 'as_string' => sub {
my $orig = shift; my $orig = shift;
my $self = shift; my $self = shift;
$self->freeze my $hashref = $self->as_hash;
my $json = JSON::Any->objToJson( $hashref );
utf8::decode($json) if !utf8::is_utf8($json) and utf8::valid($json); # if it's valid utf8 mark it as such
return $json;
}; };


#sub stringify { shift->freeze }


1; 1;


Expand Down Expand Up @@ -45,18 +50,19 @@ Log::Message::Structured::Stringify::AsJSON - JSON log lines
=head1 DESCRIPTION =head1 DESCRIPTION
Implelements the C<stringify> method required by L<Log::Message::Structured>, by delegateing to Augments the C<as_string> method provided by L<Log::Message::Structured> as a, by delegateing to
the C<freeze> method provided by L<Log::Message::Structured>, and thus returning a JSON string. the C<objToJson> from L<JSON::Any> module, and thus returning a JSON string.
=head1 METHODS =head1 METHODS
=head2 stringify =head2 as_string
Calls the freeze method (provided by L<Log::Message::Structured> to return JSON. Returns the event as JSON
=head1 AUTHOR AND COPYRIGHT =head1 AUTHOR AND COPYRIGHT
Tomas Doran (t0m) C<< <bobtfish@bobtfish.net> >>. Tomas Doran (t0m) C<< <bobtfish@bobtfish.net> >>.
Damien Krotkine (dams) C<< <dams@cpan.org> >>.
=head1 LICENSE =head1 LICENSE
Expand Down
17 changes: 7 additions & 10 deletions lib/Log/Message/Structured/Stringify/Sprintf.pm
Expand Up @@ -29,19 +29,13 @@ role {
default => '', default => '',
); );


around 'stringify' => sub { around 'as_string' => sub {
my $orig = shift; my $orig = shift;
my $self = shift; my $self = shift;
$self->previous_string($self->$orig(@_)); $self->previous_string($self->$orig(@_));
sprintf($format_string, map { defined() ? $_ : '<undef>' } map { $self->$_ } @attributes); sprintf($format_string, map { defined() ? $_ : '<undef>' } @{$self->as_hash}{@attributes} );
}; };


# method stringify => sub {
# my $self = shift;
# # FIXME - Find the correct reader name rather than assuming
# # attribute name == accessor name.
# sprintf($format_string, map { defined() ? $_ : '<undef>' } map { $self->$_ } @attributes);
# };
}; };


1; 1;
Expand All @@ -58,6 +52,8 @@ Log::Message::Structured::Stringify::Sprintf - Traditional style log lines
use Moose; use Moose;
use namespace::autoclean; use namespace::autoclean;
with 'Log::Message::Structured';
has [qw/ foo bar /] => ( is => 'ro', required => 1 ); has [qw/ foo bar /] => ( is => 'ro', required => 1 );
# Note: you MUST compose these together and after defining your attributes! # Note: you MUST compose these together and after defining your attributes!
Expand All @@ -76,8 +72,8 @@ Log::Message::Structured::Stringify::Sprintf - Traditional style log lines
=head1 DESCRIPTION =head1 DESCRIPTION
Implelements the C<stringify> method required by L<Log::Message::Structured> as Augments the C<as_string> method provided by L<Log::Message::Structured> as a
a parameterised Moose role. parameterised Moose role.
=head1 PARAMETERS =head1 PARAMETERS
Expand All @@ -93,6 +89,7 @@ produce the output.
=head1 AUTHOR AND COPYRIGHT =head1 AUTHOR AND COPYRIGHT
Tomas Doran (t0m) C<< <bobtfish@bobtfish.net> >>. Tomas Doran (t0m) C<< <bobtfish@bobtfish.net> >>.
Damien Krotkine (dams) C<< <dams@cpan.org> >>.
=head1 LICENSE =head1 LICENSE
Expand Down

0 comments on commit 649c42a

Please sign in to comment.