Ubox
OpenWrt core utilities
syslog.c File Reference
#include <linux/un.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <regex.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <syslog.h>
#include <errno.h>
#include <ctype.h>
#include <libubox/uloop.h>
#include <libubox/usock.h>
#include <libubox/ustream.h>
#include <libubox/utils.h>

Go to the source code of this file.

Macros

#define LOG_DEFAULT_SIZE   (16 * 1024)
 
#define LOG_DEFAULT_SOCKET   "/dev/log"
 
#define SYSLOG_PADDING   16
 
#define KLOG_DEFAULT_PROC   "/proc/kmsg"
 
#define PAD(x)   (x % 4) ? (((x) - (x % 4)) + 4) : (x)
 

Functions

static struct log_headlog_next (struct log_head *h, int size)
 
static uint64_t get_kernel_ts (const char *ts_sec, const char *ts_nsec)
 
static void log_add_udebug (int priority, char *buf, int size, int source)
 
void log_add (char *buf, int size, int source)
 
static void syslog_handle_fd (struct uloop_fd *fd, unsigned int events)
 
static void klog_cb (struct ustream *s, int bytes)
 
static int klog_open (void)
 
static int syslog_open (void)
 
struct log_headlog_list (int count, struct log_head *h)
 
int log_buffer_init (int size)
 
void log_udebug_config (struct udebug_ubus *ctx, struct blob_attr *data, bool enabled)
 
void log_init (int _log_size)
 

Variables

static char * log_dev = "/dev/log"
 
static int log_size = (16 * 1024)
 
static struct log_headlog
 
static struct log_headlog_end
 
static struct log_headoldest
 
static struct log_headnewest
 
static int current_id = 0
 
static regex_t pat_prio
 
static regex_t pat_tstamp
 
static struct udebug ud
 
static struct udebug_buf udb_kernel udb_user udb_debug
 
static const struct udebug_buf_meta meta_kernel
 
static const struct udebug_buf_meta meta_user
 
static const struct udebug_buf_meta meta_debug
 
static struct udebug_ubus_ring rings []
 
static struct uloop_fd syslog_fd
 
static struct ustream_fd klog
 

Macro Definition Documentation

◆ KLOG_DEFAULT_PROC

#define KLOG_DEFAULT_PROC   "/proc/kmsg"

Definition at line 42 of file syslog.c.

◆ LOG_DEFAULT_SIZE

#define LOG_DEFAULT_SIZE   (16 * 1024)

Definition at line 38 of file syslog.c.

◆ LOG_DEFAULT_SOCKET

#define LOG_DEFAULT_SOCKET   "/dev/log"

Definition at line 39 of file syslog.c.

◆ PAD

#define PAD (   x)    (x % 4) ? (((x) - (x % 4)) + 4) : (x)

Definition at line 44 of file syslog.c.

◆ SYSLOG_PADDING

#define SYSLOG_PADDING   16

Definition at line 40 of file syslog.c.

Function Documentation

◆ get_kernel_ts()

static uint64_t get_kernel_ts ( const char *  ts_sec,
const char *  ts_nsec 
)
static

Definition at line 96 of file syslog.c.

97 {
98  uint64_t ts = strtoull(ts_sec, NULL, 10) * UDEBUG_TS_SEC +
99  strtoull(ts_nsec, NULL, 10) / 1000;
100  struct timespec wall, mono;
101 
102  if (clock_gettime(CLOCK_REALTIME, &wall) ||
103  clock_gettime(CLOCK_MONOTONIC, &mono))
104  return 0;
105 
106  ts += (wall.tv_sec - mono.tv_sec) * UDEBUG_TS_SEC;
107  ts += (wall.tv_nsec - mono.tv_nsec) / 1000;
108 
109  return ts;
110 }
Here is the caller graph for this function:

◆ klog_cb()

static void klog_cb ( struct ustream *  s,
int  bytes 
)
static

Definition at line 245 of file syslog.c.

246 {
247  struct ustream_buf *buf = s->r.head;
248  char *newline, *str;
249  int len;
250 
251  do {
252  str = ustream_get_read_buf(s, NULL);
253  if (!str)
254  break;
255  newline = strchr(buf->data, '\n');
256  if (!newline)
257  break;
258  *newline = 0;
259  len = newline + 1 - str;
260  log_add(buf->data, len, SOURCE_KLOG);
261  ustream_consume(s, len);
262  } while (1);
263 }
void log_add(char *buf, int size, int source)
Definition: syslog.c:147
@ SOURCE_KLOG
Definition: syslog.h:22

◆ klog_open()

static int klog_open ( void  )
static

Definition at line 275 of file syslog.c.

276 {
277  int fd;
278 
279  fd = open(KLOG_DEFAULT_PROC, O_RDONLY | O_NONBLOCK);
280  if (fd < 0) {
281  fprintf(stderr, "Failed to open %s\n", KLOG_DEFAULT_PROC);
282  return -1;
283  }
284  fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
285  ustream_fd_init(&klog, fd);
286  return 0;
287 }
static struct ustream_fd klog
Definition: syslog.c:269
#define KLOG_DEFAULT_PROC
Definition: syslog.c:42
Here is the caller graph for this function:

◆ log_add()

void log_add ( char *  buf,
int  size,
int  source 
)

Definition at line 147 of file syslog.c.

148 {
149  regmatch_t matches[3];
150  struct log_head *next;
151  int priority = 0;
152  int ret;
153  char *c;
154 
155  /* bounce out if we don't have init'ed yet (regmatch etc will blow) */
156  if (!log) {
157  fprintf(stderr, "%s", buf);
158  return;
159  }
160 
161  for (c = buf; *c; c++) {
162  if (*c == '\n')
163  *c = ' ';
164  }
165 
166  c = buf + size - 2;
167  while (isspace(*c)) {
168  size--;
169  c--;
170  }
171 
172  buf[size - 1] = 0;
173 
174  /* strip the priority */
175  ret = regexec(&pat_prio, buf, 3, matches, 0);
176  if (!ret) {
177  priority = atoi(&buf[matches[1].rm_so]);
178  size -= matches[2].rm_so;
179  buf += matches[2].rm_so;
180  }
181 
182  /* strip syslog timestamp */
183  if ((source == SOURCE_SYSLOG) && (size > SYSLOG_PADDING) && (buf[SYSLOG_PADDING - 1] == ' ')) {
184  size -= SYSLOG_PADDING;
185  buf += SYSLOG_PADDING;
186  }
187 
189 
190  /* debug message */
191  if ((priority & LOG_FACMASK) == LOG_LOCAL7)
192  return;
193 
194  /* find new oldest entry */
195  next = log_next(newest, size);
196  if (next > newest) {
197  while ((oldest > newest) && (oldest <= next) && (oldest != log))
199  } else {
200  //fprintf(stderr, "Log wrap\n");
201  newest->size = 0;
202  next = log_next(log, size);
203  for (oldest = log; oldest <= next; oldest = log_next(oldest, oldest->size))
204  ;
205  newest = log;
206  }
207 
208  /* add the log message */
209  newest->size = size;
210  newest->id = current_id++;
212  newest->source = source;
213  clock_gettime(CLOCK_REALTIME, &newest->ts);
214  strcpy(newest->data, buf);
215 
217 
218  newest = next;
219 }
void ubus_notify_log(struct log_head *l)
Definition: logd.c:208
char data[]
Definition: syslog.h:34
unsigned int size
Definition: syslog.h:29
int source
Definition: syslog.h:32
unsigned int id
Definition: syslog.h:30
struct timespec ts
Definition: syslog.h:33
int priority
Definition: syslog.h:31
static regex_t pat_prio
Definition: syslog.c:50
#define SYSLOG_PADDING
Definition: syslog.c:40
static int current_id
Definition: syslog.c:49
static struct log_head * oldest
Definition: syslog.c:48
static struct log_head * log
Definition: syslog.c:48
static struct log_head * log_next(struct log_head *h, int size)
Definition: syslog.c:88
static void log_add_udebug(int priority, char *buf, int size, int source)
Definition: syslog.c:113
static struct log_head * newest
Definition: syslog.c:48
@ SOURCE_SYSLOG
Definition: syslog.h:23
Here is the call graph for this function:
Here is the caller graph for this function:

◆ log_add_udebug()

static void log_add_udebug ( int  priority,
char *  buf,
int  size,
int  source 
)
static

Definition at line 113 of file syslog.c.

114 {
115  regmatch_t matches[4];
116  struct udebug_buf *udb;
117  uint64_t ts = 0;
118 
119  if (source == SOURCE_KLOG)
120  udb = &udb_kernel;
121  else if ((priority & LOG_FACMASK) == LOG_LOCAL7)
122  udb = &udb_debug;
123  else
124  udb = &udb_user;
125 
126  if (!udebug_buf_valid(udb))
127  return;
128 
129  if (source == SOURCE_KLOG &&
130  !regexec(&pat_tstamp, buf, 4, matches, 0)) {
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;
134  }
135 
136  if (!ts)
137  ts = udebug_timestamp();
138 
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);
143 }
static struct udebug_buf udb_kernel udb_user udb_debug
Definition: syslog.c:53
static uint64_t get_kernel_ts(const char *ts_sec, const char *ts_nsec)
Definition: syslog.c:96
static regex_t pat_tstamp
Definition: syslog.c:51
Here is the call graph for this function:
Here is the caller graph for this function:

◆ log_buffer_init()

int log_buffer_init ( int  size)

Definition at line 328 of file syslog.c.

329 {
330  struct log_head *_log = calloc(1, size);
331 
332  if (!_log) {
333  fprintf(stderr, "Failed to initialize log buffer with size %d\n", log_size);
334  return -1;
335  }
336 
337  if (log && ((log_size + sizeof(struct log_head)) < size)) {
338  struct log_head *start = _log;
339  struct log_head *end = ((void*) _log) + size;
340  struct log_head *l;
341 
342  l = log_list(0, NULL);
343  while ((start < end) && l && l->size) {
344  memcpy(start, l, PAD(sizeof(struct log_head) + l->size));
345  start = (struct log_head *) &l->data[PAD(l->size)];
346  l = log_list(0, l);
347  }
348  free(log);
349  newest = start;
350  newest->size = 0;
351  oldest = log = _log;
352  log_end = ((void*) log) + size;
353  } else {
354  oldest = newest = log = _log;
355  log_end = ((void*) log) + size;
356  }
357  log_size = size;
358 
359  return 0;
360 }
struct log_head * log_list(int count, struct log_head *h)
Definition: syslog.c:305
static int log_size
Definition: syslog.c:47
#define PAD(x)
Definition: syslog.c:44
static struct log_head * log_end
Definition: syslog.c:48
Here is the call graph for this function:
Here is the caller graph for this function:

◆ log_init()

void log_init ( int  _log_size)

Definition at line 369 of file syslog.c.

Here is the call graph for this function:

◆ log_list()

struct log_head* log_list ( int  count,
struct log_head h 
)

Definition at line 305 of file syslog.c.

306 {
307  unsigned int min = count;
308 
309  if (count)
310  min = (count < current_id) ? (current_id - count) : (0);
311  if (!h && oldest->id >= min)
312  return oldest;
313  if (!h)
314  h = oldest;
315 
316  while (h != newest) {
317  h = log_next(h, h->size);
318  if (!h->size && (h > newest))
319  h = log;
320  if (h->id >= min && (h != newest))
321  return h;
322  }
323 
324  return NULL;
325 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ log_next()

static struct log_head* log_next ( struct log_head h,
int  size 
)
static

Definition at line 88 of file syslog.c.

89 {
90  struct log_head *n = (struct log_head *) &h->data[PAD(size)];
91 
92  return (n >= log_end) ? (log) : (n);
93 }
Here is the caller graph for this function:

◆ log_udebug_config()

void log_udebug_config ( struct udebug_ubus *  ctx,
struct blob_attr *  data,
bool  enabled 
)

Definition at line 362 of file syslog.c.

364 {
365  udebug_ubus_apply_config(&ud, rings, ARRAY_SIZE(rings), data, enabled);
366 }
static struct udebug ud
Definition: syslog.c:52
static struct udebug_ubus_ring rings[]
Definition: syslog.c:66

◆ syslog_handle_fd()

static void syslog_handle_fd ( struct uloop_fd *  fd,
unsigned int  events 
)
static

Definition at line 222 of file syslog.c.

223 {
224  static char buf[LOG_LINE_SIZE];
225  int len;
226 
227  while (1) {
228  len = recv(fd->fd, buf, LOG_LINE_SIZE - 1, 0);
229  if (len < 0) {
230  if (errno == EINTR)
231  continue;
232 
233  break;
234  }
235  if (!len)
236  break;
237 
238  buf[len] = 0;
239 
240  log_add(buf, strlen(buf) + 1, SOURCE_SYSLOG);
241  }
242 }
#define LOG_LINE_SIZE
Definition: syslog.h:17
Here is the call graph for this function:

◆ syslog_open()

static int syslog_open ( void  )
static

Definition at line 290 of file syslog.c.

291 {
292  unlink(log_dev);
293  syslog_fd.fd = usock(USOCK_UNIX | USOCK_UDP | USOCK_SERVER | USOCK_NONBLOCK, log_dev, NULL);
294  if (syslog_fd.fd < 0) {
295  fprintf(stderr,"Failed to open %s\n", log_dev);
296  return -1;
297  }
298  chmod(log_dev, 0666);
299  uloop_fd_add(&syslog_fd, ULOOP_READ | ULOOP_EDGE_TRIGGER);
300 
301  return 0;
302 }
static struct uloop_fd syslog_fd
Definition: syslog.c:265
static char * log_dev
Definition: syslog.c:46
Here is the caller graph for this function:

Variable Documentation

◆ current_id

int current_id = 0
static

Definition at line 49 of file syslog.c.

◆ klog

struct ustream_fd klog
static
Initial value:
= {
.stream.string_data = true,
.stream.notify_read = klog_cb,
}
static void klog_cb(struct ustream *s, int bytes)
Definition: syslog.c:245

Definition at line 245 of file syslog.c.

◆ log

struct log_head* log
static

Definition at line 48 of file syslog.c.

◆ log_dev

char* log_dev = "/dev/log"
static

Definition at line 46 of file syslog.c.

◆ log_end

struct log_head * log_end
static

Definition at line 48 of file syslog.c.

◆ log_size

int log_size = (16 * 1024)
static

Definition at line 47 of file syslog.c.

◆ meta_debug

const struct udebug_buf_meta meta_debug
static
Initial value:
= {
.name = "debug",
.format = UDEBUG_FORMAT_STRING,
}

Definition at line 51 of file syslog.c.

◆ meta_kernel

const struct udebug_buf_meta meta_kernel
static
Initial value:
= {
.name = "kernel",
.format = UDEBUG_FORMAT_STRING,
}

Definition at line 51 of file syslog.c.

◆ meta_user

const struct udebug_buf_meta meta_user
static
Initial value:
= {
.name = "syslog",
.format = UDEBUG_FORMAT_STRING,
}

Definition at line 51 of file syslog.c.

◆ newest

struct log_head * newest
static

Definition at line 48 of file syslog.c.

◆ oldest

struct log_head * oldest
static

Definition at line 48 of file syslog.c.

◆ pat_prio

regex_t pat_prio
static

Definition at line 50 of file syslog.c.

◆ pat_tstamp

regex_t pat_tstamp
static

Definition at line 51 of file syslog.c.

◆ rings

struct udebug_ubus_ring rings[]
static
Initial value:
= {
{
.buf = &udb_kernel,
.meta = &meta_kernel,
.default_entries = 1024,
.default_size = 65536,
},
{
.buf = &udb_user,
.meta = &meta_user,
.default_entries = 1024,
.default_size = 65536,
},
{
.buf = &udb_debug,
.meta = &meta_debug,
.default_entries = 1024,
.default_size = 65536,
},
}
static const struct udebug_buf_meta meta_debug
Definition: syslog.c:62
static const struct udebug_buf_meta meta_kernel
Definition: syslog.c:54
static const struct udebug_buf_meta meta_user
Definition: syslog.c:58

Definition at line 51 of file syslog.c.

◆ syslog_fd

struct uloop_fd syslog_fd
static
Initial value:
= {
}
static void syslog_handle_fd(struct uloop_fd *fd, unsigned int events)
Definition: syslog.c:222

Definition at line 245 of file syslog.c.

◆ ud

struct udebug ud
static

Definition at line 51 of file syslog.c.

◆ udb_debug

struct udebug_buf udb_kernel udb_user udb_debug
static

Definition at line 51 of file syslog.c.