Commit a6b257f0 authored by Pavel Emelyanov's avatar Pavel Emelyanov

log-simple: Use buffering before output to log file

Multi-task/thread apps spoil log as simple logger does
char-by-char output.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent c5aa77f8
...@@ -3,9 +3,47 @@ ...@@ -3,9 +3,47 @@
#include "log.h" #include "log.h"
#include "log-levels.h" #include "log-levels.h"
#define LOG_SIMPLE_CHUNK 72
struct simple_buf {
char buf[LOG_SIMPLE_CHUNK];
char *bp;
};
static int logfd = -1; static int logfd = -1;
static int cur_loglevel = DEFAULT_LOGLEVEL; static int cur_loglevel = DEFAULT_LOGLEVEL;
static void sbuf_init(struct simple_buf *b)
{
b->buf[0] = 'p';
b->buf[1] = 'i';
b->buf[2] = 'e';
b->buf[3] = ':';
b->buf[4] = ' ';
b->bp = b->buf + 5;
}
static void sbuf_flush(struct simple_buf *b)
{
if (b->bp == b->buf + 5)
return;
sys_write(logfd, b->buf, b->bp - b->buf);
sbuf_init(b);
}
static void sbuf_putc(struct simple_buf *b, char c)
{
*b->bp = c;
b->bp++;
if (b->bp - b->buf >= LOG_SIMPLE_CHUNK - 2) {
b->bp[0] = '>';
b->bp[1] = '\n';
b->bp += 2;
sbuf_flush(b);
}
}
void log_set_fd(int fd) void log_set_fd(int fd)
{ {
sys_close(logfd); sys_close(logfd);
...@@ -17,12 +55,12 @@ void log_set_loglevel(unsigned int level) ...@@ -17,12 +55,12 @@ void log_set_loglevel(unsigned int level)
cur_loglevel = level; cur_loglevel = level;
} }
static void print_string(const char *msg) static void print_string(const char *msg, struct simple_buf *b)
{ {
int size = 0; while (*msg) {
while (msg[size]) sbuf_putc(b, *msg);
size++; msg++;
sys_write(logfd, msg, size); }
} }
int vprint_num(char *buf, int blen, int num, char **ps) int vprint_num(char *buf, int blen, int num, char **ps)
...@@ -57,20 +95,22 @@ done: ...@@ -57,20 +95,22 @@ done:
return blen - (s - buf); return blen - (s - buf);
} }
static void print_num(int num) static void print_num(int num, struct simple_buf *b)
{ {
char buf[11], *s; char buf[12], *s;
int len; int len;
len = vprint_num(buf, sizeof(buf), num, &s); buf[11] = '\0';
sys_write(logfd, s, len); len = vprint_num(buf, sizeof(buf) - 1, num, &s);
print_string(buf + sizeof(buf) - len, b);
} }
static void print_num_l(long num) static void print_num_l(long num, struct simple_buf *b)
{ {
int neg = 0; int neg = 0;
char buf[21], *s; char buf[22], *s;
buf[21] = '\0';
s = &buf[20]; s = &buf[20];
if (num < 0) { if (num < 0) {
...@@ -94,7 +134,7 @@ static void print_num_l(long num) ...@@ -94,7 +134,7 @@ static void print_num_l(long num)
} }
done: done:
s++; s++;
sys_write(logfd, s, sizeof(buf) - (s - buf)); print_string(s, b);
} }
static void hexdigit(unsigned int v, char *to, char **z) static void hexdigit(unsigned int v, char *to, char **z)
...@@ -104,10 +144,11 @@ static void hexdigit(unsigned int v, char *to, char **z) ...@@ -104,10 +144,11 @@ static void hexdigit(unsigned int v, char *to, char **z)
*z = to; *z = to;
} }
static void print_hex(unsigned int num) static void print_hex(unsigned int num, struct simple_buf *b)
{ {
char buf[10], *z = &buf[9]; char buf[11], *z = &buf[9];
buf[10] = '\0';
hexdigit(num >> 0, &buf[9], &z); hexdigit(num >> 0, &buf[9], &z);
hexdigit(num >> 4, &buf[8], &z); hexdigit(num >> 4, &buf[8], &z);
hexdigit(num >> 8, &buf[7], &z); hexdigit(num >> 8, &buf[7], &z);
...@@ -120,13 +161,14 @@ static void print_hex(unsigned int num) ...@@ -120,13 +161,14 @@ static void print_hex(unsigned int num)
z[0] = '0'; z[0] = '0';
z[1] = 'x'; z[1] = 'x';
sys_write(logfd, z, sizeof(buf) - (z - buf)); print_string(z, b);
} }
static void print_hex_l(unsigned long num) static void print_hex_l(unsigned long num, struct simple_buf *b)
{ {
char buf[18], *z = &buf[17]; char buf[19], *z = &buf[17];
buf[18] = '\0';
hexdigit(num >> 0, &buf[17], &z); hexdigit(num >> 0, &buf[17], &z);
hexdigit(num >> 4, &buf[16], &z); hexdigit(num >> 4, &buf[16], &z);
hexdigit(num >> 8, &buf[15], &z); hexdigit(num >> 8, &buf[15], &z);
...@@ -151,31 +193,33 @@ static void print_hex_l(unsigned long num) ...@@ -151,31 +193,33 @@ static void print_hex_l(unsigned long num)
z[0] = '0'; z[0] = '0';
z[1] = 'x'; z[1] = 'x';
sys_write(logfd, z, sizeof(buf) - (z - buf)); print_string(z, b);
} }
void print_on_level(unsigned int loglevel, const char *format, ...) void print_on_level(unsigned int loglevel, const char *format, ...)
{ {
va_list args; va_list args;
const char *s = format, *p; const char *s = format;
struct simple_buf b;
if (loglevel > cur_loglevel) if (loglevel > cur_loglevel)
return; return;
sbuf_init(&b);
va_start(args, format); va_start(args, format);
p = s;
while (1) { while (1) {
int along = 0; int along = 0;
if (*s != '\0' && *s != '%') { if (*s == '\0')
break;
if (*s != '%') {
sbuf_putc(&b, *s);
s++; s++;
continue; continue;
} }
sys_write(logfd, p, s - p);
if (*s == '\0')
break;
s++; s++;
if (*s == 'l') { if (*s == 'l') {
along = 1; along = 1;
...@@ -184,23 +228,24 @@ void print_on_level(unsigned int loglevel, const char *format, ...) ...@@ -184,23 +228,24 @@ void print_on_level(unsigned int loglevel, const char *format, ...)
switch (*s) { switch (*s) {
case 's': case 's':
print_string(va_arg(args, char *)); print_string(va_arg(args, char *), &b);
break; break;
case 'd': case 'd':
if (along) if (along)
print_num_l(va_arg(args, long)); print_num_l(va_arg(args, long), &b);
else else
print_num(va_arg(args, int)); print_num(va_arg(args, int), &b);
break; break;
case 'x': case 'x':
if (along) if (along)
print_hex_l(va_arg(args, long)); print_hex_l(va_arg(args, long), &b);
else else
print_hex(va_arg(args, unsigned int)); print_hex(va_arg(args, unsigned int), &b);
break; break;
} }
s++; s++;
p = s;
} }
va_end(args); va_end(args);
sbuf_flush(&b);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment