diff options
| author | Odd Stranne <odd@mullvad.net> | 2018-08-29 12:13:31 +0200 |
|---|---|---|
| committer | Odd Stranne <odd@mullvad.net> | 2018-09-04 13:06:33 +0200 |
| commit | 0379da796c4436f6800cd65e02219a0843270dc3 (patch) | |
| tree | 84af72486c8c0d6276dbee44cff32ab27f57415e /windows/nsis-plugins/src/log/logger.cpp | |
| parent | 1d5be836d3aea89ce3e75eabcae8a3e7d5df1c83 (diff) | |
| download | mullvadvpn-0379da796c4436f6800cd65e02219a0843270dc3.tar.xz mullvadvpn-0379da796c4436f6800cd65e02219a0843270dc3.zip | |
Add NSIS 'log' plugin
Diffstat (limited to 'windows/nsis-plugins/src/log/logger.cpp')
| -rw-r--r-- | windows/nsis-plugins/src/log/logger.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/windows/nsis-plugins/src/log/logger.cpp b/windows/nsis-plugins/src/log/logger.cpp new file mode 100644 index 0000000000..f22bf84bf1 --- /dev/null +++ b/windows/nsis-plugins/src/log/logger.cpp @@ -0,0 +1,111 @@ +#include "stdafx.h" +#include "logger.h" +#include <libcommon/error.h> +#include <libcommon/string.h> +#include <sstream> +#include <iomanip> + +AnsiFileLogSink::AnsiFileLogSink(const std::wstring &file, bool append, bool flush) + : m_flush(flush) +{ + const DWORD creationDisposition = (append ? OPEN_ALWAYS : CREATE_ALWAYS); + + m_logfile = CreateFileW(file.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, nullptr, + creationDisposition, FILE_ATTRIBUTE_NORMAL, nullptr); + + THROW_GLE_IF(INVALID_HANDLE_VALUE, m_logfile, "Open/create log file"); + + if (append && ERROR_ALREADY_EXISTS == GetLastError()) + { + LARGE_INTEGER offset = { 0 }; + + const auto seekStatus = SetFilePointerEx(m_logfile, offset, nullptr, FILE_END); + + THROW_GLE_IF(FALSE, seekStatus, "Seek to end offset in existing log file"); + } +} + +AnsiFileLogSink::~AnsiFileLogSink() +{ + CloseHandle(m_logfile); +} + +void AnsiFileLogSink::log(const std::wstring &message) +{ + auto ansi = common::string::ToAnsi(message); + + ansi.append("\xd\xa"); + + DWORD bytesWritten; + + WriteFile(m_logfile, ansi.c_str(), ansi.size(), &bytesWritten, nullptr); + + if (m_flush) + { + FlushFileBuffers(m_logfile); + } +} + +void Logger::log(const std::wstring &message) +{ + m_logsink->log(Compose(message, Timestamp(), ordinal())); +} + +void Logger::log(const std::wstring &message, const std::vector<std::wstring> &details) +{ + const auto timestamp = this->Timestamp(); + const auto ordinal = this->ordinal(); + + m_logsink->log(Compose(message, timestamp, ordinal)); + + // + // Write details with indentation. + // + for (const auto detail : details) + { + m_logsink->log(Compose(detail, timestamp, ordinal, 4)); + } +} + +// static +std::wstring Logger::Timestamp() +{ + SYSTEMTIME time; + + GetLocalTime(&time); + + std::wstringstream ss; + + ss << L'[' + << std::right << std::setw(2) << std::setfill(L'0') << time.wHour + << L':' + << std::right << std::setw(2) << std::setfill(L'0') << time.wMinute + << L':' + << std::right << std::setw(2) << std::setfill(L'0') << time.wSecond + << L']'; + + return ss.str(); +} + +std::wstring Logger::ordinal() +{ + std::wstringstream ss; + + ss << std::right << std::setw(4) << std::setfill(L' ') << m_ordinal++; + + return ss.str(); +} + +//static +std::wstring Logger::Compose(const std::wstring &message, const std::wstring ×tamp, + const std::wstring &ordinal, size_t indentation) +{ + std::wstringstream ss; + + ss << timestamp << L' ' + << ordinal << L' ' + << std::wstring(indentation, L' ') + << message; + + return ss.str(); +} |
