#include "pch.h"
#include "Extensions/Logging/FileLoggerProvider.h"
#include "Extensions/Logging/FileLogger.h"
#include "Extensions/Logging/LogManager.h"
#include "System/IO/Path.h"
#include "System/IO/Directory.h"
#include "System/IOException.h"
#include "FileLoggerContext.h"
namespace DotNetDupe {
namespace Extensions {
namespace Logging {
FileLoggerProvider::FileLoggerProvider()
: FileLoggerProvider(LogManager::GetConfiguration()) {
}
static DotNetDupe::System::String ResolveAndPrepareLogPath(const DotNetDupe::System::String& rawFilePath) {
using namespace DotNetDupe::System::IO;
DotNetDupe::System::String targetPath = rawFilePath;
if (targetPath.IsEmpty()) {
targetPath = "logs/app.log";
}
DotNetDupe::System::String fullPath = Path::GetFullPath(targetPath);
DotNetDupe::System::String parentDir = Path::GetDirectoryName(fullPath);
if (!parentDir.IsEmpty() && !Directory::Exists(parentDir)) {
Directory::CreateDirectory(parentDir, true);
}
return fullPath;
}
struct FileLoggerProvider::Impl {
LoggerConfiguration config;
DotNetDupe::System::SmartPointer<FileLoggerContext> pContext;
};
FileLoggerProvider::FileLoggerProvider(const LoggerConfiguration& config)
: m_pImpl(DotNetDupe::System::SmartPointer<Impl>::NewShared()) {
m_pImpl->config = config;
m_pImpl->config.FilePath = ResolveAndPrepareLogPath(config.FilePath);
m_pImpl->pContext = DotNetDupe::System::SmartPointer<FileLoggerContext>::NewShared();
m_pImpl->pContext->fileMutex = std::make_shared<std::mutex>();
m_pImpl->pContext->fileStream = std::make_shared<std::ofstream>(m_pImpl->config.FilePath.GetRawString(), std::ios::out | std::ios::app);
}
FileLoggerProvider::FileLoggerProvider(const DotNetDupe::System::String& filePath, bool isJsonFormat, LogLevel minLevel)
: m_pImpl(DotNetDupe::System::SmartPointer<Impl>::NewShared()) {
m_pImpl->config.FilePath = ResolveAndPrepareLogPath(filePath);
m_pImpl->config.IsJsonFormat = isJsonFormat;
m_pImpl->config.MinLevel = minLevel;
m_pImpl->pContext = DotNetDupe::System::SmartPointer<FileLoggerContext>::NewShared();
m_pImpl->pContext->fileMutex = std::make_shared<std::mutex>();
m_pImpl->pContext->fileStream = std::make_shared<std::ofstream>(m_pImpl->config.FilePath.GetRawString(), std::ios::out | std::ios::app);
}
FileLoggerProvider::~FileLoggerProvider() {
if (m_pImpl && m_pImpl->pContext && m_pImpl->pContext->fileMutex && m_pImpl->pContext->fileStream) {
std::lock_guard<std::mutex> lock(*(m_pImpl->pContext->fileMutex));
if (m_pImpl->pContext->fileStream->is_open()) {
m_pImpl->pContext->fileStream->close();
}
}
}
const DotNetDupe::System::String& FileLoggerProvider::GetFilePath() const {
return m_pImpl->config.FilePath;
}
DotNetDupe::System::SmartPointer<ILogger> FileLoggerProvider::CreateLogger(const DotNetDupe::System::String& categoryName) {
return DotNetDupe::System::SmartPointer<FileLogger>::NewShared(categoryName, m_pImpl->config, m_pImpl->pContext);
}
}
}
}