16 #include <sys/types.h>
17 #include <sys/socket.h>
31 #include <libubox/uloop.h>
32 #include <libubox/usock.h>
33 #include <libubox/ustream.h>
34 #include <libubox/utils.h>
38 #define LOG_DEFAULT_SIZE (16 * 1024)
39 #define LOG_DEFAULT_SOCKET "/dev/log"
40 #define SYSLOG_PADDING 16
42 #define KLOG_DEFAULT_PROC "/proc/kmsg"
44 #define PAD(x) (x % 4) ? (((x) - (x % 4)) + 4) : (x)
53 static struct udebug_buf udb_kernel, udb_user,
udb_debug;
56 .format = UDEBUG_FORMAT_STRING,
58 static const struct udebug_buf_meta
meta_user = {
60 .format = UDEBUG_FORMAT_STRING,
62 static const struct udebug_buf_meta
meta_debug = {
64 .format = UDEBUG_FORMAT_STRING,
66 static struct udebug_ubus_ring
rings[] = {
70 .default_entries = 1024,
71 .default_size = 65536,
76 .default_entries = 1024,
77 .default_size = 65536,
82 .default_entries = 1024,
83 .default_size = 65536,
98 uint64_t
ts = strtoull(ts_sec, NULL, 10) * UDEBUG_TS_SEC +
99 strtoull(ts_nsec, NULL, 10) / 1000;
100 struct timespec wall, mono;
102 if (clock_gettime(CLOCK_REALTIME, &wall) ||
103 clock_gettime(CLOCK_MONOTONIC, &mono))
106 ts += (wall.tv_sec - mono.tv_sec) * UDEBUG_TS_SEC;
107 ts += (wall.tv_nsec - mono.tv_nsec) / 1000;
115 regmatch_t matches[4];
116 struct udebug_buf *udb;
121 else if ((priority & LOG_FACMASK) == LOG_LOCAL7)
126 if (!udebug_buf_valid(udb))
131 ts =
get_kernel_ts(&buf[matches[1].rm_so], &buf[matches[2].rm_so]);
132 buf += matches[3].rm_so;
133 size -= matches[3].rm_so;
137 ts = udebug_timestamp();
139 udebug_entry_init_ts(udb, ts);
140 udebug_entry_printf(udb,
"<%d>", priority);
141 udebug_entry_append(udb, buf, size - 1);
142 udebug_entry_add(udb);
149 regmatch_t matches[3];
157 fprintf(stderr,
"%s", buf);
161 for (c = buf; *c; c++) {
167 while (isspace(*c)) {
175 ret = regexec(&
pat_prio, buf, 3, matches, 0);
177 priority = atoi(&buf[matches[1].rm_so]);
178 size -= matches[2].rm_so;
179 buf += matches[2].rm_so;
191 if ((
priority & LOG_FACMASK) == LOG_LOCAL7)
213 clock_gettime(CLOCK_REALTIME, &
newest->
ts);
247 struct ustream_buf *buf = s->r.head;
252 str = ustream_get_read_buf(s, NULL);
255 newline = strchr(buf->data,
'\n');
259 len = newline + 1 - str;
261 ustream_consume(s, len);
269 static struct ustream_fd
klog = {
270 .stream.string_data =
true,
284 fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
285 ustream_fd_init(&
klog, fd);
293 syslog_fd.fd = usock(USOCK_UNIX | USOCK_UDP | USOCK_SERVER | USOCK_NONBLOCK,
log_dev, NULL);
295 fprintf(stderr,
"Failed to open %s\n",
log_dev);
299 uloop_fd_add(&
syslog_fd, ULOOP_READ | ULOOP_EDGE_TRIGGER);
307 unsigned int min = count;
333 fprintf(stderr,
"Failed to initialize log buffer with size %d\n",
log_size);
343 while ((start < end) && l && l->
size) {
374 regcomp(&
pat_prio,
"^<([0-9]*)>(.*)", REG_EXTENDED);
375 regcomp(&
pat_tstamp,
"^\\[[ 0]*([0-9]*).([0-9]*)\\] (.*)", REG_EXTENDED);
378 fprintf(stderr,
"Failed to allocate log memory\n");
383 udebug_auto_connect(&
ud, NULL);
384 for (
size_t i = 0; i < ARRAY_SIZE(
rings); i++)
385 udebug_ubus_ring_init(&
ud, &
rings[i]);
389 openlog(
"sysinit", LOG_CONS, LOG_DAEMON);
400 ustream_free(&
klog.stream);
void ubus_notify_log(struct log_head *l)
static struct udebug_ubus udebug
static struct ubus_context * ctx
static struct ustream_fd klog
static struct udebug_buf udb_kernel udb_user udb_debug
struct log_head * log_list(int count, struct log_head *h)
void log_add(char *buf, int size, int source)
static void syslog_handle_fd(struct uloop_fd *fd, unsigned int events)
static uint64_t get_kernel_ts(const char *ts_sec, const char *ts_nsec)
static struct uloop_fd syslog_fd
static int klog_open(void)
static int syslog_open(void)
static regex_t pat_tstamp
#define KLOG_DEFAULT_PROC
static struct log_head * oldest
static void klog_cb(struct ustream *s, int bytes)
static const struct udebug_buf_meta meta_debug
static struct log_head * log
static const struct udebug_buf_meta meta_kernel
static struct log_head * log_next(struct log_head *h, int size)
static void log_add_udebug(int priority, char *buf, int size, int source)
static struct udebug_ubus_ring rings[]
void log_init(int _log_size)
static struct log_head * log_end
int log_buffer_init(int size)
void log_udebug_config(struct udebug_ubus *ctx, struct blob_attr *data, bool enabled)
static struct log_head * newest
static const struct udebug_buf_meta meta_user
#define LOG_DEFAULT_SOCKET