Skip to content

Commit 51daa90

Browse files
committed
Verious bug fixes, and started wrapping the library calls
The ability to pass pointers to flb_input, flb_filter and flb_output was broken. I have it correctly permitting undef values for NULLs now. then I wrapped the API in LibFluentBit with more perlish methods, including tracking whether the engine is started so that it can be cleanly shut down. Then I wrote a simple logger object that writes timestamped messages into the 'lib' input. Added some unit tests, and it seems to be working.
1 parent 498ae5a commit 51daa90

File tree

6 files changed

+143
-8
lines changed

6 files changed

+143
-8
lines changed

LibFluentBit.xs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
#ifndef newSVivpv
99
static SV *newSVivpv(IV ival, const char *pval) {
1010
SV *s= newSVpv(pval, 0);
11-
SvIOK_on(s);
11+
SvUPGRADE(s, SVt_PVIV);
1212
SvIV_set(s, ival);
13+
SvIOK_on(s);
1314
return s;
1415
}
1516
#endif
@@ -43,10 +44,16 @@ flb_service_set(ctx, ...)
4344
RETVAL
4445

4546
int
46-
flb_input(ctx, name, data=NULL)
47+
flb_input(ctx, name, data_sv=NULL)
4748
flb_ctx_t *ctx
4849
const char *name
49-
void *data
50+
SV *data_sv
51+
INIT:
52+
void *data= data_sv && SvOK(data_sv)? (void*)SvIV(data_sv) : NULL;
53+
CODE:
54+
RETVAL= flb_input(ctx, name, data);
55+
OUTPUT:
56+
RETVAL
5057

5158
int
5259
flb_input_set(ctx, in_ffd, ...)
@@ -73,10 +80,16 @@ flb_input_set(ctx, in_ffd, ...)
7380
RETVAL
7481

7582
int
76-
flb_filter(ctx, name, data=NULL)
83+
flb_filter(ctx, name, data_sv=NULL)
7784
flb_ctx_t *ctx
7885
const char *name
79-
void *data
86+
SV *data_sv
87+
INIT:
88+
void *data= data_sv && SvOK(data_sv)? (void*)SvIV(data_sv) : NULL;
89+
CODE:
90+
RETVAL= flb_filter(ctx, name, data);
91+
OUTPUT:
92+
RETVAL
8093

8194
int
8295
flb_filter_set(ctx, flt_ffd, ...)
@@ -103,10 +116,16 @@ flb_filter_set(ctx, flt_ffd, ...)
103116
RETVAL
104117

105118
int
106-
flb_output(ctx, name, data=NULL)
119+
flb_output(ctx, name, data_sv=NULL)
107120
flb_ctx_t *ctx
108121
const char *name
109-
void *data
122+
SV *data_sv
123+
INIT:
124+
void *data= data_sv && SvOK(data_sv)? (void*)SvIV(data_sv) : NULL;
125+
CODE:
126+
RETVAL= flb_output(ctx, name, data);
127+
OUTPUT:
128+
RETVAL
110129

111130
int
112131
flb_output_set(ctx, out_ffd, ...)
@@ -148,7 +167,7 @@ flb_destroy(obj)
148167
CODE:
149168
if (ctx) {
150169
flb_destroy(ctx);
151-
PerlFluentBit_set_ctx_mg(obj, NULL); // unset magic so that can't be called twice
170+
PerlFluentBit_set_ctx_mg(obj, NULL);
152171
}
153172

154173
int

lib/Fluent/LibFluentBit.pm

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,61 @@
11
package Fluent::LibFluentBit;
22
use strict;
33
use warnings;
4+
use Carp;
5+
use JSON::MaybeXS;
46

57
# VERSION
68
# ABSTRACT: Perl interface to libfluent-bit.so
79

810
require XSLoader;
911
XSLoader::load('Fluent::LibFluentBit', $Fluent::LibFluentBit::VERSION);
1012

13+
my $default_instance;
14+
sub default_instance {
15+
$default_instance //= Fluent::LibFluentBit->new;
16+
}
17+
18+
sub new {
19+
my $class= shift;
20+
my $self= Fluent::LibFluentBit::flb_create();
21+
%$self= (@_ == 1 && ref $_[0] eq 'HASH')? %{$_[0]} : @_;
22+
$self->{started}= !1;
23+
return $self;
24+
}
25+
26+
sub started { $_[0]{started} }
27+
28+
sub start {
29+
my $self= shift;
30+
unless ($self->{started}) {
31+
$self->flb_start;
32+
$self->{started}= 1;
33+
}
34+
}
35+
36+
sub stop {
37+
my $self= shift;
38+
if ($self->{started}) {
39+
$self->flb_stop;
40+
$self->{started}= 0;
41+
}
42+
}
43+
44+
sub DESTROY {
45+
my $self= shift;
46+
$self->stop;
47+
$self->flb_destroy;
48+
}
49+
50+
sub new_logger {
51+
my $self= shift;
52+
require Fluent::LibFluentBit::Logger;
53+
$self->start unless $self->{started};
54+
Fluent::LibFluentBit::Logger->new(context => $self, @_);
55+
}
56+
57+
END {
58+
undef $default_instance;
59+
}
60+
1161
1;

lib/Fluent/LibFluentBit/Logger.pm

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package Fluent::LibFluentBit::Logger;
2+
use strict;
3+
use warnings;
4+
use Carp;
5+
use JSON::MaybeXS;
6+
7+
sub new {
8+
my $class= shift;
9+
my %attrs= @_;
10+
defined $attrs{context} or croak "Missing required attribute 'context'";
11+
$attrs{ffd} //= $attrs{context}->flb_input("lib");
12+
$attrs{ffd} >= 0 or croak "Can't create 'lib' input to libfluent-bit";
13+
bless \%attrs, $class;
14+
}
15+
16+
sub _log_data {
17+
my ($self, $data, $level)= @_;
18+
$data= { message => $data } unless ref $data eq 'HASH';
19+
my $code= $self->{context}->flb_lib_push($self->{ffd}, encode_json([ time, $data ]));
20+
$code >= 0 or croak "flb_lib_push failed: $code";
21+
return $self;
22+
}
23+
24+
sub info {
25+
$_[0]->_log_data( $_[1], 'info' );
26+
}
27+
28+
sub warn {
29+
$_[0]->_log_data( $_[1], 'warn' );
30+
}
31+
32+
sub error {
33+
$_[0]->_log_data( $_[1], 'error' );
34+
}
35+
36+
1;
37+

t/01-init.t

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ use Test::More;
44

55
use_ok( 'Fluent::LibFluentBit' ) or BAIL_OUT;
66

7+
is( Fluent::LibFluentBit::FLB_LIB_OK(), 'FLB_LIB_OK', 'constants by name' );
8+
is( 0+Fluent::LibFluentBit::FLB_LIB_OK(), 1, 'constants by value' );
9+
710
ok( my $flb= Fluent::LibFluentBit::flb_create(), 'flb_create' );
811
local $@;
912
is( eval { $flb->flb_destroy; 1; }, 1, 'flb_destroy' )

t/02-simple-logging.t

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use strict;
2+
use warnings;
3+
use Test::More;
4+
use Fluent::LibFluentBit;
5+
6+
my $y2020= 1577836800;
7+
ok( my $flb= Fluent::LibFluentBit::flb_create(), 'flb_create' );
8+
ok( (my $in_ffd= $flb->flb_input("lib", undef)) >= 0, 'flb_input' );
9+
ok( (my $out_ffd= $flb->flb_output("stdout", undef)) >= 0, 'flb_output' );
10+
ok( $flb->flb_start >= 0, 'flb_start' );
11+
ok( $flb->flb_lib_push($in_ffd, qq|[ $y2020, { "message":"Hello World" } ]|) >= 0, 'flb_lib_push' );
12+
ok( $flb->flb_stop >= 0, 'flb_stop' );
13+
ok( eval { undef $flb; 1; }, 'flb_destroy via undef' );
14+
15+
done_testing;

t/03-logger-obj.t

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use strict;
2+
use warnings;
3+
use Test::More;
4+
use Fluent::LibFluentBit;
5+
6+
ok( my $flb= Fluent::LibFluentBit->default_instance, 'default_instance' );
7+
ok( my $logger= $flb->new_logger, 'new_logger' );
8+
ok( $logger->error('test'), "error('test')" );
9+
undef $flb;
10+
11+
done_testing;

0 commit comments

Comments
 (0)