Skip to content

Commit

Permalink
#5231: Working on the Logging subsystem
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Apr 28, 2020
1 parent 6e2305a commit 08024cd
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 55 deletions.
8 changes: 8 additions & 0 deletions include/iradiant.h
Expand Up @@ -7,6 +7,8 @@

const char* const MODULE_RADIANT("Radiant");

namespace applog { class ILogWriter; }

namespace radiant
{

Expand All @@ -18,6 +20,12 @@ class IRadiant
public:
typedef std::shared_ptr<IRadiant> Ptr;

/**
* Central logging class of the module. Use this to
* attach your own ILogDevices to receive logging output.
*/
virtual applog::ILogWriter& getLogWriter() = 0;

virtual ~IRadiant() {}
};

Expand Down
18 changes: 17 additions & 1 deletion radiant/Radiant.cpp
@@ -1,6 +1,9 @@
#include "iradiant.h"
#include "module/CoreModule.h"

#include "log/LogStream.h"
#include "log/LogWriter.h"

namespace radiant
{

Expand All @@ -13,7 +16,20 @@ class Radiant :
public:
Radiant(ApplicationContext& context) :
_context(context)
{}
{
// Set the stream references for rMessage(), redirect std::cout, etc.
applog::LogStream::InitialiseStreams();
}

~Radiant()
{
applog::LogStream::ShutdownStreams();
}

applog::ILogWriter& getLogWriter() override
{
return applog::LogWriter::Instance();
}
};

}
Expand Down
58 changes: 50 additions & 8 deletions radiant/RadiantApp.cpp
Expand Up @@ -2,6 +2,7 @@

#include "i18n.h"
#include "iradiant.h"
#include "version.h"

#include "log/LogFile.h"
#include "log/LogStream.h"
Expand All @@ -26,6 +27,7 @@
#include <libintl.h>
#endif
#include <exception>
#include <iomanip>

#if defined (_DEBUG) && defined (WIN32) && defined (_MSC_VER)
#include "crtdbg.h"
Expand All @@ -34,6 +36,11 @@
// The startup event which will be queued in App::OnInit()
wxDEFINE_EVENT(EV_RadiantStartup, wxCommandEvent);

namespace
{
const char* const TIME_FMT = "%Y-%m-%d %H:%M:%S";
}

bool RadiantApp::OnInit()
{
if (!wxApp::OnInit()) return false;
Expand Down Expand Up @@ -67,8 +74,8 @@ bool RadiantApp::OnInit()
throw ex;
}

// The settings path is set, start logging now
applog::LogFile::create("darkradiant.log");
// Attach the logfile to the core binary's logwriter
createLogFile();

#ifndef POSIX
// Initialise the language based on the settings in the user settings folder
Expand Down Expand Up @@ -101,19 +108,54 @@ bool RadiantApp::OnInit()
return true;
}

int RadiantApp::OnExit()
void RadiantApp::createLogFile()
{
if (_coreModule)
_logFile.reset(new applog::LogFile(_context.getSettingsPath() + "darkradiant.log"));

if (_logFile->isOpen())
{
_coreModule.reset();
_coreModule->get()->getLogWriter().attach(_logFile.get());

rMessage() << "Started logging to " << _logFile->getFullPath() << std::endl;

rMessage() << "This is " << RADIANT_APPNAME_FULL() << std::endl;

std::time_t t = std::time(nullptr);
std::tm tm = *std::localtime(&t);

// Write timestamp and thread information
rMessage() << "Today is " << std::put_time(&tm, TIME_FMT) << std::endl;

// Output the wxWidgets version to the logfile
std::string wxVersion = string::to_string(wxMAJOR_VERSION) + ".";
wxVersion += string::to_string(wxMINOR_VERSION) + ".";
wxVersion += string::to_string(wxRELEASE_NUMBER);

rMessage() << "wxWidgets Version: " << wxVersion << std::endl;
}
else
{
rConsoleError() << "Failed to create log file '"
<< _logFile->getFullPath() << ", check write permissions in parent directory."
<< std::endl;
}
}

int RadiantApp::OnExit()
{
// Issue a shutdown() call to all the modules
module::GlobalModuleRegistry().shutdownModules();

// Close the logfile
applog::LogFile::close();
applog::LogStream::ShutdownStreams();
if (_coreModule)
{
// Close the log file
if (_logFile)
{
_coreModule->get()->getLogWriter().detach(_logFile.get());
}

_coreModule.reset();
}

return wxApp::OnExit();
}
Expand Down
4 changes: 4 additions & 0 deletions radiant/RadiantApp.h
Expand Up @@ -3,6 +3,7 @@
#include <wx/app.h>
#include "modulesystem/ApplicationContextImpl.h"
#include "module/CoreModule.h"
#include "log/LogFile.h"

/**
* Main application class required by wxWidgets
Expand All @@ -24,6 +25,8 @@ class RadiantApp :

std::unique_ptr<module::CoreModule> _coreModule;

std::unique_ptr<applog::LogFile> _logFile;

public:
bool OnInit() override;
int OnExit() override;
Expand All @@ -34,5 +37,6 @@ class RadiantApp :
bool OnExceptionInMainLoop() override;

private:
void createLogFile();
void onStartupEvent(wxCommandEvent& ev);
};
38 changes: 17 additions & 21 deletions radiant/log/LogFile.cpp
Expand Up @@ -9,7 +9,6 @@

#include "string/convert.h"
#include "LogWriter.h"
#include "modulesystem/ModuleRegistry.h"

namespace applog
{
Expand All @@ -19,25 +18,10 @@ namespace
const char* const TIME_FMT = "%Y-%m-%d %H:%M:%S";
}

LogFile::LogFile(const std::string& filename) :
_logFilename(
module::ModuleRegistry::Instance().getApplicationContext().getSettingsPath() +
filename
),
_logStream(_logFilename.c_str())
{
if (_logStream.good())
{
// Register this class as logdevice
LogWriter::Instance().attach(this);
}
else
{
rConsoleError() << "Failed to create log file '"
<< _logFilename << ", check write permissions in parent directory."
<< std::endl;
}
}
LogFile::LogFile(const std::string& fullPath) :
_logFilePath(fullPath),
_logStream(_logFilePath.c_str())
{}

LogFile::~LogFile()
{
Expand All @@ -63,6 +47,16 @@ LogFile::~LogFile()
LogWriter::Instance().detach(this);
}

bool LogFile::isOpen()
{
return _logStream.good();
}

const std::string& LogFile::getFullPath() const
{
return _logFilePath;
}

void LogFile::writeLog(const std::string& outputStr, ELogLevel level)
{
_buffer.append(outputStr);
Expand All @@ -88,6 +82,7 @@ void LogFile::writeLog(const std::string& outputStr, ELogLevel level)
}
}

#if 0
// Creates the singleton logfile with the given filename
void LogFile::create(const std::string& filename)
{
Expand All @@ -97,7 +92,7 @@ void LogFile::create(const std::string& filename)
InstancePtr() = LogFilePtr(new LogFile(filename));

// Write the initialisation info to the logfile.
rMessage() << "Started logging to " << InstancePtr()->_logFilename << std::endl;
rMessage() << "Started logging to " << InstancePtr()->_logFilePath << std::endl;

rMessage() << "This is " << RADIANT_APPNAME_FULL() << std::endl;

Expand Down Expand Up @@ -128,5 +123,6 @@ LogFilePtr& LogFile::InstancePtr() {
static LogFilePtr _instancePtr;
return _instancePtr;
}
#endif

} // namespace applog
28 changes: 9 additions & 19 deletions radiant/log/LogFile.h
@@ -1,21 +1,16 @@
#pragma once

#include <fstream>
#include <memory>
#include "ilogwriter.h"

namespace applog
{

// Shared_ptr forward declaration
class LogFile;
typedef std::shared_ptr<LogFile> LogFilePtr;

class LogFile :
public ILogDevice
{
// The log file name including path
std::string _logFilename;
std::string _logFilePath;

// We write line by line
std::string _buffer;
Expand All @@ -25,28 +20,23 @@ class LogFile :

public:
/**
* greebo: Pass only the file name to the constructor,
* the path is automatically loaded from the XMLRegistry.
* (The path in the registry key SETTINGS_PATH is used.)
* greebo: Pass the full path to the constructor
*/
LogFile(const std::string& filename);
LogFile(const std::string& fullPath);

virtual ~LogFile();

// Returns true if the log stream was successfully opened
bool isOpen();

// Returns the full path to the log file
const std::string& getFullPath() const;

/**
* Use this to write a string to the logfile. This usually gets
* called by the LogWriter class, but it can be called independently.
*/
void writeLog(const std::string& outputStr, ELogLevel level) override;

// Creates the singleton logfile with the given filename
static void create(const std::string& filename);

// Closes the singleton log instance
static void close();

// The singleton InstancePtr(), is NULL when the logfile is closed
static LogFilePtr& InstancePtr();
};

} // namespace applog
4 changes: 0 additions & 4 deletions tools/msvc/DarkRadiantCore.vcxproj
Expand Up @@ -117,19 +117,15 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\..\..\install\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\..\..\install\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\..\..\install\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\..\..\install\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
Expand Down
4 changes: 2 additions & 2 deletions tools/msvc/modulelib.vcxproj
Expand Up @@ -94,7 +94,7 @@
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand All @@ -106,7 +106,7 @@
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand Down

0 comments on commit 08024cd

Please sign in to comment.