3 #define __USE_GNU /* F_SETPIPE_SZ */
8 #include <murphy/common/log.h>
9 #include <murphy/common/mainloop.h>
11 #include "sphinx-plugin.h"
13 #define SPHINX_INFO "INFO: "
14 #define SPHINX_ERROR "ERROR: "
15 #define SPHINX_WARN "WARNING: "
16 #define SPHINX_SYSERR "SYSTEM_ERROR: "
17 #define SPHINX_FATAL "FATAL_ERROR: "
23 int fd[2]; /* log message pipe */
24 FILE *fp; /* log write stream */
25 mrp_io_watch_t *w; /* log I/O watch */
26 char buf[4096]; /* log line buffer */
31 static ssize_t pull_log(logger_t *logger)
36 p = logger->buf + logger->n;
37 l = sizeof(logger->buf) - logger->n - 1;
39 n = read(logger->fd[RD], p, l);
51 static void push_log(logger_t *logger)
53 char *b, *e, *lb, *le, *file, lvl, name[1024];
57 name[sizeof(name) - 1] = '\0';
62 while (logger->n > 0) {
65 if (!strncmp(b, SPHINX_INFO , len = sizeof(SPHINX_INFO ) - 1) ||
66 !strncmp(b, SPHINX_WARN , len = sizeof(SPHINX_WARN ) - 1) ||
67 !strncmp(b, SPHINX_ERROR , len = sizeof(SPHINX_ERROR ) - 1) ||
68 !strncmp(b, SPHINX_SYSERR, len = sizeof(SPHINX_SYSERR) - 1) ||
69 !strncmp(b, SPHINX_FATAL , len = sizeof(SPHINX_FATAL ) - 1)) {
77 if ((e = strchr(b, '\n')) == NULL) {
78 if (logger->n >= sizeof(logger->buf) - 1) {
79 mrp_log_warning("Discarding too long sphinx log buffer.");
86 line = (int)strtoul(lb + 1, &le, 10);
88 if (lb != NULL && *le == ')') {
90 snprintf(name, sizeof(name) - 1, "%*.*s", nlen, nlen, b);
93 if (b[0] == ':' && b[1] == ' ')
99 file = "<unknown-file>";
107 mrp_debug_at("sphinx", line, file, "%*.*s", n, n, b);
110 mrp_log_msg(MRP_LOG_WARNING, file, line, "sphinx", "%*.*s", n, n, b);
115 mrp_log_msg(MRP_LOG_ERROR, file, line, "sphinx", "%*.*s", n, n, b);
120 n = logger->n - (b - logger->buf);
125 memmove(logger->buf, b, n);
127 logger->buf[n] = '\0';
133 static void log_cb(mrp_io_watch_t *w, int fd, mrp_io_event_t events,
136 logger_t *logger = (logger_t *)user_data;
140 if (events & MRP_IO_EVENT_IN)
141 while (pull_log(logger) > 0)
144 if (events & MRP_IO_EVENT_HUP)
149 FILE *logger_create(context_t *ctx)
151 static logger_t logger = { { -1, -1 }, NULL, 0 };
152 mrp_mainloop_t *ml = plugin_get_mainloop(ctx->plugin);
153 mrp_io_event_t events = MRP_IO_EVENT_IN | MRP_IO_EVENT_HUP;
155 if (logger.fp != NULL)
158 if (pipe(logger.fd) < 0) {
159 mrp_log_error("Failed to create sphinx logging pipe (error %d: %s).",
160 errno, strerror(errno));
164 if ((logger.fp = fdopen(logger.fd[WR], "w")) == NULL)
167 setvbuf(logger.fp, NULL, _IOLBF, 0);
169 fcntl(logger.fd[WR], F_SETPIPE_SZ, 512 * 1024);
170 fcntl(logger.fd[WR], F_SETFL, O_NONBLOCK);
171 fcntl(logger.fd[RD], F_SETFL, O_NONBLOCK);
173 logger.w = mrp_add_io_watch(ml, logger.fd[RD], events, log_cb, &logger);
175 if (logger.w != NULL)
183 if (logger.fp != NULL)