1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <systemd/sd-journal.h>
sd_journal *j;
void split_data_to_svs(const char *msg, SV **k_sv, SV **v_sv) {
char *data_copy = strdup(msg);
char *k = strtok(data_copy, "=");
char *v = strtok(NULL, "=");
(*k_sv) = newSVpv(k, strlen(k));
(*v_sv) = newSVpv(v, strlen(v));
}
MODULE = Linux::Systemd::Journal::Read PACKAGE = Linux::Systemd::Journal::Read
PROTOTYPES: ENABLE
NO_OUTPUT void
__open()
CODE:
int r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
if (r < 0)
croak("Failed to open journal: %s\n", strerror(r));
//
// NO_OUTPUT void
// __open_files(path)
// CODE:
// int r = sd_journal_open_files(&j, path, SD_JOURNAL_LOCAL_ONLY);
// if (r < 0)
// croak("Failed to open journal: %s\n", strerror(r));
uint64_t
get_usage(self)
CODE:
int r = sd_journal_get_usage(j, &RETVAL);
if (r < 0)
croak("Failed to open journal: %s\n", strerror(-r));
OUTPUT: RETVAL
int
next(self, uint64_t skip=0)
CODE:
if (skip > 0)
RETVAL = sd_journal_next_skip(j, skip);
else
RETVAL = sd_journal_next(j);
POSTCALL:
if (RETVAL < 0)
croak("Failed to move to next record: %s\n", strerror(-RETVAL));
OUTPUT: RETVAL
int
previous(self, uint64_t skip=0)
CODE:
if (skip > 0)
RETVAL = sd_journal_previous_skip(j, skip);
else
RETVAL = sd_journal_previous(j);
POSTCALL:
if (RETVAL < 0)
croak("Failed to move to previous record: %s\n", strerror(-RETVAL));
OUTPUT: RETVAL
NO_OUTPUT void
seek_head(self)
CODE:
int r = sd_journal_seek_head(j);
if (r < 0)
croak("Failed to seek to journal head: %s\n", strerror(-r));
NO_OUTPUT void
seek_tail(self)
CODE:
int r = sd_journal_seek_tail(j);
if (r < 0)
croak("Failed to seek to journal tail: %s\n", strerror(-r));
NO_OUTPUT void
wait(self)
CODE:
int r = sd_journal_wait(j, (uint64_t) -1);
if (r < 0)
croak("Failed to wait for changes: %s\n", strerror(-r));
SV *
get_data(self, const char *field)
CODE:
SV *key_sv;
char *data;
size_t l;
int r = sd_journal_get_data(j, field, (const void**) &data, &l);
if (r < 0)
croak("Failed to read message field '%s': %s\n", field, strerror(-r));
split_data_to_svs(data, &key_sv, &RETVAL);
OUTPUT: RETVAL
HV *
get_entry(self)
PREINIT:
const void *data;
size_t l;
SV *key_sv, *val_sv;
int r;
CODE:
RETVAL = newHV();
sd_journal_restart_data(j);
while ((r = sd_journal_enumerate_data(j, &data, &l)) > 0) {
split_data_to_svs(data, &key_sv, &val_sv);
hv_store_ent(RETVAL, key_sv, val_sv, 0);
}
if (r < 0)
croak("Failed to get entry data: %s\n", strerror(-r));
OUTPUT: RETVAL
# TODO should take binary data as well
NO_OUTPUT void
__add_match(const char *data)
CODE:
int r = sd_journal_add_match(j, data, 0);
if (r < 0)
croak("Failed to add a match: %s\n", strerror(-r));
NO_OUTPUT void
__match_and()
CODE:
int r = sd_journal_add_conjunction(j);
if (r < 0)
croak("Failed to set conjunction: %s\n", strerror(-r));
NO_OUTPUT void
__match_or()
CODE:
int r = sd_journal_add_disjunction(j);
if (r < 0)
croak("Failed to set disjunction: %s\n", strerror(-r));
NO_OUTPUT void
flush_matches(self)
CODE:
sd_journal_flush_matches(j);
NO_OUTPUT void
DESTROY(self)
CODE:
sd_journal_close(j);
|