Skip to content

Commit

Permalink
Support log backends, add a file log backend.
Browse files Browse the repository at this point in the history
  • Loading branch information
dscharrer committed Oct 8, 2011
1 parent 203449e commit 9c928c0
Show file tree
Hide file tree
Showing 17 changed files with 600 additions and 111 deletions.
24 changes: 21 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ else(MSVC)
check_symbol_exists(readlink "unistd.h" HAVE_READLINK)
check_symbol_exists(dup2 "unistd.h" HAVE_DUP2)
check_symbol_exists(execlp "unistd.h" HAVE_EXECLP)
check_symbol_exists(isatty "unistd.h" HAVE_ISATTY)
check_symbol_exists(waitpid "sys/wait.h" HAVE_WAITPID)
check_symbol_exists(kill "signal.h" HAVE_KILL)
check_symbol_exists(signal "signal.h" HAVE_SIGNAL)
Expand Down Expand Up @@ -414,7 +415,6 @@ set(INPUT_DINPUT8_SOURCES src/input/DInput8Backend.cpp)
set(INPUT_SDL_SOURCES src/input/SDLInputBackend.cpp)

set(IO_SOURCES
src/io/log/Logger.cpp
src/io/Blast.cpp
src/io/CinematicLoad.cpp
src/io/Implode.cpp
Expand All @@ -427,6 +427,13 @@ set(IO_SOURCES
src/io/SaveBlock.cpp
src/io/Screenshot.cpp
)
set(IO_LOGGER_SOURCES
src/io/log/ConsoleLogger.cpp
src/io/log/FileLogger.cpp
src/io/log/Logger.cpp
)
set(IO_LOGGER_POSIX_SOURCES src/io/log/ColorLogger.cpp)
set(IO_LOGGER_WINDOWS_SOURCES src/io/log/MsvcLogger.cpp)
set(IO_FILESYSTEM_SOURCES
src/io/FilePath.cpp
src/io/FileStream.cpp
Expand Down Expand Up @@ -561,6 +568,14 @@ if(ARX_USE_DINPUT8)
endif()
endif()

if(HAVE_ISATTY)
list(APPEND IO_LOGGER_SOURCES ${IO_LOGGER_POSIX_SOURCES})
endif()
if(HAVE_WINAPI)
list(APPEND IO_SOURCES ${IO_LOGGER_WINDOWS_SOURCES})
endif()
list(APPEND IO_SOURCES ${IO_LOGGER_SOURCES})

if(HAVE_POSIX_FILESYSTEM)
list(APPEND IO_FILESYSTEM_SOURCES ${IO_FILESYSTEM_POSIX_SOURCES})
elseif(HAVE_WINAPI)
Expand Down Expand Up @@ -611,8 +626,8 @@ if(ARX_BUILD_TOOLS)

set(SAVETOOL_SOURCES
${IO_FILESYSTEM_SOURCES}
${IO_LOGGER_SOURCES}
src/core/Localisation.cpp
src/io/log/Logger.cpp
src/io/PakEntry.cpp
src/io/PakReader.cpp
src/io/Blast.cpp
Expand All @@ -632,10 +647,13 @@ if(ARX_BUILD_TOOLS)

set(UNPAK_SOURCES
${IO_FILESYSTEM_SOURCES}
src/io/log/Logger.cpp
${IO_LOGGER_SOURCES}
src/io/PakEntry.cpp
src/io/PakReader.cpp
src/io/Blast.cpp
src/io/log/ColorLogger.cpp
src/io/log/ConsoleLogger.cpp
src/io/log/Logger.cpp
src/platform/String.cpp
src/platform/Platform.cpp
tools/unpak/unpak.cpp
Expand Down
1 change: 1 addition & 0 deletions src/Configure.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#cmakedefine HAVE_SIGNAL
#cmakedefine HAVE_BACKTRACE
#cmakedefine HAVE_BACKTRACE_SYMBOLS_FD
#cmakedefine HAVE_ISATTY

// Compiler features
#cmakedefine HAVE_DYNAMIC_STACK_ALLOCATION
Expand Down
5 changes: 5 additions & 0 deletions src/core/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
#include "io/PakReader.h"
#include "io/CinematicLoad.h"
#include "io/Screenshot.h"
#include "io/log/FileLogger.h"
#include "io/log/Logger.h"

#include "math/Angle.h"
Expand Down Expand Up @@ -639,6 +640,10 @@ int main(int argc, char ** argv) {

initCrashHandler();

Logger::init();

Logger::add(new logger::File("arx.log", std::ios_base::out | std::ios_base::trunc));

FOR_EXTERNAL_PEOPLE = 1; // TODO remove this

ALLOW_CHEATS = 0;
Expand Down
30 changes: 30 additions & 0 deletions src/io/log/ColorLogger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

#include "io/log/ColorLogger.h"

#include <iostream>

namespace logger {

ColorConsole::~ColorConsole() {
// nothing to clean up
}

void ColorConsole::log(const Source & file, int line, Logger::LogLevel level, const std::string & str) {

std::ostream * os;
switch(level) {
case Logger::Debug: std::cout << "\e[1;36m[D]\e[0;36m", os = &std::cout; break;
case Logger::Info: std::cout << "\e[1;32m[I]\e[0;32m", os = &std::cout; break;
case Logger::Warning: std::cerr << "\e[1;33m[W]\e[0;33m", os = &std::cerr; break;
case Logger::Error: std::cerr << "\e[1;31m[E]\e[0;31m", os = &std::cerr; break;
case Logger::None: ARX_DEAD_CODE();
}

(*os) << ' ' << file.name << "\e[m:\e[0;33m" << line << "\e[m" << " " << str << std::endl;
}

void ColorConsole::flush() {
std::cout.flush(), std::cerr.flush();
}

} // namespace logger
26 changes: 26 additions & 0 deletions src/io/log/ColorLogger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

#ifndef ARX_IO_LOG_COLORLOGGER_H
#define ARX_IO_LOG_COLORLOGGER_H

#include "io/log/LogBackend.h"

namespace logger {

/*!
* ConsoleLogger that colors output message using shell color codes.
*/
class ColorConsole : public Backend {

public:

~ColorConsole();

void log(const Source & file, int line, Logger::LogLevel level, const std::string & str);

void flush();

};

} // namespace logger

#endif // ARX_IO_LOG_COLORLOGGER_H
67 changes: 67 additions & 0 deletions src/io/log/ConsoleLogger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

#include "io/log/ConsoleLogger.h"

#include <cstring>
#include <iostream>

#include "io/log/ColorLogger.h"

#include "Configure.h"

namespace logger {

Console::~Console() {
// nothing to clean up
}

void Console::log(const Source & file, int line, Logger::LogLevel level, const std::string & str) {

std::ostream * os;
switch(level) {
case Logger::Debug: std::cout << "[D]", os = &std::cout; break;
case Logger::Info: std::cout << "[I]", os = &std::cout; break;
case Logger::Warning: std::cerr << "[W]", os = &std::cerr; break;
case Logger::Error: std::cerr << "[E]", os = &std::cerr; break;
case Logger::None: ARX_DEAD_CODE();
}

(*os) << ' ' << file.name << ':' << line << " " << str << std::endl;
}

void Console::flush() {
std::cout.flush(), std::cerr.flush();
}

static bool is_fd_disabled(int fd) {

ARX_UNUSED(fd);

// Disable the console log backend if output is redirected to /dev/null
#ifdef HAVE_READLINK
static const char * names[] = { NULL, "/proc/self/fd/1", "/proc/self/fd/2" };
char path[64];
ssize_t len = readlink(names[fd], path, ARRAY_SIZE(path));
if(len == 9 && !memcmp(names, "/dev/null", 9)) {
return true;
}
#endif

return false;
}

Backend * Console::get() {

#ifdef HAVE_ISATTY
if(isatty(1) && isatty(2)) {
return new ColorConsole;
}
#endif

if(is_fd_disabled(1) && is_fd_disabled(2)) {
return NULL;
}

return new Console;
}

} // namespace logger
32 changes: 32 additions & 0 deletions src/io/log/ConsoleLogger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

#ifndef ARX_IO_LOG_CONSOLELOGGER_H
#define ARX_IO_LOG_CONSOLELOGGER_H

#include "io/log/LogBackend.h"

namespace logger {

/*!
* Simple logger that prints plain text to standard output.
*/
class Console : public Backend {

public:

~Console();

void log(const Source & file, int line, Logger::LogLevel level, const std::string & str);

void flush();

/*!
* @return a ColorLogger instance if colors are supported or a ConsoleLogger otherwise.
* May return null if standard output / error is discarded.
*/
static Backend * get();

};

} // namespace logger

#endif // ARX_IO_LOG_CONSOLELOGGER_H
31 changes: 31 additions & 0 deletions src/io/log/FileLogger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

#include "io/log/FileLogger.h"

#include "io/log/ColorLogger.h"

#include "Configure.h"

namespace logger {

File::~File() {
// nothing to clean up
}

void File::log(const Source & file, int line, Logger::LogLevel level, const std::string & str) {

switch(level) {
case Logger::Debug: ofs << "[D]"; break;
case Logger::Info: ofs << "[I]"; break;
case Logger::Warning: ofs << "[W]"; break;
case Logger::Error: ofs << "[E]"; break;
case Logger::None: ARX_DEAD_CODE();
}

ofs << ' ' << file.name << ':' << line << " " << str << std::endl;
}

void File::flush() {
ofs.flush();
}

} // namespace logger
32 changes: 32 additions & 0 deletions src/io/log/FileLogger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

#ifndef ARX_IO_LOG_FILELOGGER_H
#define ARX_IO_LOG_FILELOGGER_H

#include "io/FileStream.h"
#include "io/log/LogBackend.h"

namespace logger {

/*!
* Simple logger that prints plain text to standard output.
*/
class File : public Backend {

fs::ofstream ofs;

public:

inline File(const fs::path & path, std::ios_base::openmode mode)
: ofs(path, mode) { }

~File();

void log(const Source & file, int line, Logger::LogLevel level, const std::string & str);

void flush();

};

} // namespace logger

#endif // ARX_IO_LOG_FILELOGGER_H
Empty file added src/io/log/FileLogger.hpp
Empty file.
33 changes: 33 additions & 0 deletions src/io/log/LogBackend.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

#ifndef ARX_IO_LOG_LOGBACKEND_H
#define ARX_IO_LOG_LOGBACKEND_H

#include "io/log/Logger.h"

namespace logger {

struct Source {

const char * file;

std::string name;

Logger::LogLevel level;

};

class Backend {

public:

virtual ~Backend() { }

virtual void log(const Source & file, int line, Logger::LogLevel level, const std::string & str) = 0;

virtual void flush() = 0;

};

} // namespace logger

#endif // ARX_IO_LOG_LOGBACKEND_H
Loading

0 comments on commit 9c928c0

Please sign in to comment.