Commit 10f56705 authored by Guillaume Roguez's avatar Guillaume Roguez Committed by gerrit2

logger: rewrite

- Console mode modified for a nice look:
  - add timestamp
  - colored header
  - reordering
- Fix syslog output (openlog on "dring")
- Multithread safe (mutex protected)
- Make logger a C++ file and code cleanup

Issue: #79075
Change-Id: I6c818ec283541ce8e740693ebefbafce3cac5617
parent d7b36194
......@@ -112,7 +112,7 @@ libring_la_SOURCES = conference.cpp \
manager.cpp \
call.cpp \
account.cpp \
logger.c \
logger.cpp \
fileutils.cpp \
threadloop.cpp \
ip_utils.h \
......
/*
* Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
* Author: Julien Bonjean <julien.bonjean@savoirfairelinux.com>
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -32,17 +33,95 @@
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include <string>
#include <sstream>
#include <iomanip>
#include <ios>
#include <mutex>
#include <thread>
#include "logger.h"
static int consoleLog;
static int debugMode;
#ifdef __linux__
#include <syslog.h>
#include <unistd.h>
#include <sys/syscall.h>
#endif // __linux__
#ifdef WIN32
#include "winsyslog.h"
#endif
void logger(const int level, const char* format, ...)
#define BLACK "\033[22;30m"
#define GREEN "\033[22;32m"
#define BROWN "\033[22;33m"
#define BLUE "\033[22;34m"
#define MAGENTA "\033[22;35m"
#define GREY "\033[22;37m"
#define DARK_GREY "\033[01;30m"
#define LIGHT_RED "\033[01;31m"
#define LIGHT_SCREEN "\033[01;32m"
#define LIGHT_BLUE "\033[01;34m"
#define LIGHT_MAGENTA "\033[01;35m"
#define LIGHT_CYAN "\033[01;36m"
#define WHITE "\033[01;37m"
#define END_COLOR "\033[0m"
#ifndef _WIN32
#define RED "\033[22;31m"
#define YELLOW "\033[01;33m"
#define CYAN "\033[22;36m"
#else
#define RED FOREGROUND_RED
#define YELLOW FOREGROUND_RED + FOREGROUND_GREEN
#define CYAN FOREGROUND_BLUE + FOREGROUND_GREEN
#endif
static int consoleLog;
static int debugMode;
static std::mutex logMutex;
static std::string
getHeader(const char* ctx)
{
#ifdef __linux__
auto tid = syscall(__NR_gettid) & 0xffff;
#else
auto tid = std::this_thread::get_id();
#endif // __linux__
// Timestamp
unsigned int secs, milli;
struct timeval tv;
if (!gettimeofday(&tv, NULL)) {
secs = tv.tv_sec;
milli = tv.tv_usec / 1000; // suppose that milli < 1000
} else {
secs = time(NULL);
milli = 0;
}
std::ostringstream out;
const auto prev_fill = out.fill();
out << '[' << secs
<< '.' << std::right << std::setw(3) << std::setfill('0') << milli << std::left
<< '|' << std::right << std::setw(5) << std::setfill(' ') << tid << std::left;
out.fill(prev_fill);
// Context
if (ctx)
out << "|" << std::setw(24) << ctx;
out << "] ";
return out.str();
}
void
logger(const int level, const char* format, ...)
{
if (!debugMode && level == LOG_DEBUG)
return;
......@@ -53,8 +132,11 @@ void logger(const int level, const char* format, ...)
va_end(ap);
}
void vlogger(const int level, const char *format, va_list ap)
void
vlogger(const int level, const char *format, va_list ap)
{
std::lock_guard<std::mutex> lk {logMutex};
#ifdef WIN32
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
......@@ -66,8 +148,10 @@ void vlogger(const int level, const char *format, va_list ap)
if (consoleLog) {
#ifndef _WIN32
const char *color_prefix = "";
const char* color_header = CYAN;
const char* color_prefix = "";
#else
WORD color_header = CYAN;
WORD color_prefix = FOREGROUND_GREEN;
#endif
......@@ -81,10 +165,23 @@ void vlogger(const int level, const char *format, va_list ap)
}
#ifndef _WIN32
fputs(color_prefix, stderr);
fputs(color_header, stderr);
#else
GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
saved_attributes = consoleInfo.wAttributes;
SetConsoleTextAttribute(hConsole, color_header);
#endif
auto sep = strchr(format, '|'); // must exist, check LOG_FORMAT
std::string ctx(format, sep - format);
format = sep + 2;
fputs(getHeader(ctx.c_str()).c_str(), stderr);
#ifndef _WIN32
fputs(END_COLOR, stderr);
fputs(color_prefix, stderr);
#else
SetConsoleTextAttribute(hConsole, saved_attributes);
SetConsoleTextAttribute(hConsole, color_prefix);
#endif
......@@ -102,22 +199,36 @@ void vlogger(const int level, const char *format, va_list ap)
}
}
void setConsoleLog(int c)
void
setConsoleLog(int c)
{
if (c)
closelog();
else {
#ifdef _WIN32
openlog(LOGFILE, WINLOG_PID, WINLOG_MAIL);
#else
openlog(LOGFILE, LOG_NDELAY, LOG_USER);
#endif /* _WIN32 */
}
consoleLog = c;
}
void setDebugMode(int d)
void
setDebugMode(int d)
{
debugMode = d;
}
int getDebugMode(void)
int
getDebugMode(void)
{
return debugMode;
}
void strErr(void)
void
strErr(void)
{
#ifdef __GLIBC__
RING_ERR("%m");
......
/*
* Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
* Author: Julien Bonjean <julien.bonjean@savoirfairelinux.com>
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -28,8 +29,7 @@
* as that of the covered work.
*/
#ifndef H_LOGGER
#define H_LOGGER
#pragma once
#ifdef __cplusplus
extern "C" {
......@@ -37,11 +37,13 @@ extern "C" {
#include <stdarg.h>
#define LOGFILE "dring"
/**
* Print something, coloring it depending on the level
*/
void logger(const int level, const char *format, ...);
void vlogger(const int level, const char *format, va_list);
void logger(const int level, const char* format, ...);
void vlogger(const int level, const char* format, va_list);
/**
* Allow writing on the console
......@@ -63,19 +65,11 @@ int getDebugMode(void);
*/
void strErr();
#ifdef __linux__
#include <unistd.h>
#include <sys/syscall.h>
#define STR(EXP) #EXP
#define XSTR(X) STR(X)
#define LOG_FORMAT(M, ...) "%s:%d:0x%x: " M, FILE_NAME, __LINE__, \
syscall(__NR_gettid) & 0xffff, \
##__VA_ARGS__
#else
#define LOG_FORMAT(M, ...) "%s:%d: " M, FILE_NAME , __LINE__, \
##__VA_ARGS__
#endif
// Do not remove the "| " in following without modifying vlogger() code
#define LOG_FORMAT(M, ...) FILE_NAME ":" XSTR(__LINE__) "| " M, ##__VA_ARGS__
#ifdef __ANDROID__
......@@ -86,8 +80,7 @@ void strErr();
#endif /* APP_NAME */
// Avoid printing whole path on android
#define FILE_NAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 \
: __FILE__)
#define FILE_NAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
// because everyone likes reimplementing the wheel
#define LOG_ERR ANDROID_LOG_ERROR
......@@ -95,8 +88,7 @@ void strErr();
#define LOG_INFO ANDROID_LOG_INFO
#define LOG_DEBUG ANDROID_LOG_DEBUG
#define LOGGER(M, LEVEL, ...) __android_log_print(LEVEL, APP_NAME, \
LOG_FORMAT(M, ##__VA_ARGS__))
#define LOGGER(M, LEVEL, ...) __android_log_print(LEVEL, APP_NAME, LOG_FORMAT(M, ##__VA_ARGS__))
#elif defined(_WIN32)
......@@ -122,36 +114,10 @@ void strErr();
#endif /* __ANDROID__ _WIN32 */
#define RING_ERR(M, ...) LOGGER(M, LOG_ERR, ##__VA_ARGS__)
#define RING_WARN(M, ...) LOGGER(M, LOG_WARNING, ##__VA_ARGS__)
#define RING_INFO(M, ...) LOGGER(M, LOG_INFO, ##__VA_ARGS__)
#define RING_WARN(M, ...) LOGGER(M, LOG_WARNING, ##__VA_ARGS__)
#define RING_INFO(M, ...) LOGGER(M, LOG_INFO, ##__VA_ARGS__)
#define RING_DBG(M, ...) LOGGER(M, LOG_DEBUG, ##__VA_ARGS__)
#define BLACK "\033[22;30m"
#define GREEN "\033[22;32m"
#define BROWN "\033[22;33m"
#define BLUE "\033[22;34m"
#define MAGENTA "\033[22;35m"
#define CYAN "\033[22;36m"
#define GREY "\033[22;37m"
#define DARK_GREY "\033[01;30m"
#define LIGHT_RED "\033[01;31m"
#define LIGHT_SCREEN "\033[01;32m"
#define LIGHT_BLUE "\033[01;34m"
#define LIGHT_MAGENTA "\033[01;35m"
#define LIGHT_CYAN "\033[01;36m"
#define WHITE "\033[01;37m"
#define END_COLOR "\033[0m"
#ifndef _WIN32
#define RED "\033[22;31m"
#define YELLOW "\033[01;33m"
#else
#define RED FOREGROUND_RED
#define YELLOW FOREGROUND_RED + FOREGROUND_GREEN
#endif
#ifdef __cplusplus
}
#endif
#endif // H_LOGGER
......@@ -74,9 +74,6 @@ void closelog(void)
CONST CHAR *arr[1];
char tmp[1024];
if (!loghdl)
openlog(LOGFILE, WINLOG_PID, WINLOG_MAIL);
vsprintf(tmp, format, arglist);
arr[0] = tmp;
......@@ -105,4 +102,4 @@ void closelog(void)
loghdl = RegisterEventSource(NULL, ident);
sprintf(tmp, (logopt & WINLOG_PID) ? "%s[%d]" : "%s", ident, getpid());
loghdr = _strdup(tmp); /* save header for later */
}
\ No newline at end of file
}
......@@ -40,8 +40,6 @@
#define WINLOG_MASK(pri) (1 << (pri))
#define WINLOG_UPTO(pri) ((1 << ((pri)+1)) - 1)
#define LOGFILE "ringcli"
/*
* Option flags for openlog.
*
......@@ -61,4 +59,4 @@ extern void closelog(void);
extern void openlog(const char *, int, int);
extern void vsyslog(int, const char *, va_list);
#endif
\ No newline at end of file
#endif
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