summaryrefslogtreecommitdiff
path: root/lib/generate_logfile.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/generate_logfile.h')
-rw-r--r--lib/generate_logfile.h174
1 files changed, 102 insertions, 72 deletions
diff --git a/lib/generate_logfile.h b/lib/generate_logfile.h
index beb4f5d3..875d5b98 100644
--- a/lib/generate_logfile.h
+++ b/lib/generate_logfile.h
@@ -16,16 +16,24 @@
namespace zen
{
-Utf8String generateLogStream(const ErrorLog& log,
- const std::wstring& jobName, //may be empty
- const std::wstring& finalStatus,
- int itemsSynced, Int64 dataSynced,
- int itemsTotal, Int64 dataTotal,
- long totalTime); //unit: [sec]
-
-void saveToLastSyncsLog(const Utf8String& logstream); //throw FileError
+struct SummaryInfo
+{
+ std::wstring jobName; //may be empty
+ std::wstring finalStatus;
+ int itemsSynced;
+ Int64 dataSynced;
+ int itemsTotal;
+ Int64 dataTotal;
+ long totalTime; //unit: [sec]
+};
+void saveLogToFile(const SummaryInfo& summary, //throw FileError
+ const ErrorLog& log,
+ FileOutput& fileOut);
+void saveToLastSyncsLog(const SummaryInfo& summary, //throw FileError
+ const ErrorLog& log,
+ size_t maxBytesToWrite);
@@ -34,114 +42,136 @@ void saveToLastSyncsLog(const Utf8String& logstream); //throw FileError
//####################### implementation #######################
namespace
{
-Utf8String generateLogStream_impl(const ErrorLog& log,
- const std::wstring& jobName, //may be empty
- const std::wstring& finalStatus,
- int itemsSynced, Int64 dataSynced,
- int itemsTotal, Int64 dataTotal,
- long totalTime) //unit: [sec]
+std::wstring generateLogHeader(const SummaryInfo& s)
{
- assert(itemsSynced <= itemsTotal);
- assert(dataSynced <= dataTotal);
+ assert(s.itemsSynced <= s.itemsTotal);
+ assert(s.dataSynced <= s.dataTotal);
- Utf8String output;
+ std::wstring output;
//write header
std::wstring headerLine = formatTime<std::wstring>(FORMAT_DATE);
- if (!jobName.empty())
- headerLine += L" - " + jobName;
- headerLine += L": " + finalStatus;
+ if (!s.jobName.empty())
+ headerLine += L" - " + s.jobName;
+ headerLine += L": " + s.finalStatus;
//assemble results box
std::vector<std::wstring> results;
results.push_back(headerLine);
results.push_back(L"");
- const wchar_t tabSpace[] = L" ";
+ const wchar_t tabSpace[] = L" ";
- std::wstring itemsProc = tabSpace + _("Items processed:") + L" " + toGuiString(itemsSynced); //show always, even if 0!
- if (itemsSynced != 0 || dataSynced != 0) //[!] don't show 0 bytes processed if 0 items were processed
- itemsProc += + L" (" + filesizeToShortString(dataSynced) + L")";
+ std::wstring itemsProc = tabSpace + _("Items processed:") + L" " + toGuiString(s.itemsSynced); //show always, even if 0!
+ if (s.itemsSynced != 0 || s.dataSynced != 0) //[!] don't show 0 bytes processed if 0 items were processed
+ itemsProc += + L" (" + filesizeToShortString(s.dataSynced) + L")";
results.push_back(itemsProc);
- if (itemsTotal != 0 || dataTotal != 0) //=: sync phase was reached and there were actual items to sync
+ if (s.itemsTotal != 0 || s.dataTotal != 0) //=: sync phase was reached and there were actual items to sync
{
- if (itemsSynced != itemsTotal ||
- dataSynced != dataTotal)
- results.push_back(tabSpace + _("Items remaining:") + L" " + toGuiString(itemsTotal - itemsSynced) + L" (" + filesizeToShortString(dataTotal - dataSynced) + L")");
+ if (s.itemsSynced != s.itemsTotal ||
+ s.dataSynced != s.dataTotal)
+ results.push_back(tabSpace + _("Items remaining:") + L" " + toGuiString(s.itemsTotal - s.itemsSynced) + L" (" + filesizeToShortString(s.dataTotal - s.dataSynced) + L")");
}
- results.push_back(tabSpace + _("Total time:") + L" " + copyStringTo<std::wstring>(wxTimeSpan::Seconds(totalTime).Format()));
+ results.push_back(tabSpace + _("Total time:") + L" " + copyStringTo<std::wstring>(wxTimeSpan::Seconds(s.totalTime).Format()));
//calculate max width, this considers UTF-16 only, not true Unicode...
size_t sepLineLen = 0;
std::for_each(results.begin(), results.end(), [&](const std::wstring& str) { sepLineLen = std::max(sepLineLen, str.size()); });
- for (size_t i = 0; i < sepLineLen; ++i) output += '_'; //this considers UTF-16 only, not true Unicode!!!
- output += "\n";
-
- std::for_each(results.begin(), results.end(), [&](const std::wstring& str) { output += utfCvrtTo<Utf8String>(str); output += '\n'; });
+ for (size_t i = 0; i < sepLineLen; ++i) output += L'_'; //this considers UTF-16 only, not true Unicode!!!
+ output += L'\n';
- for (size_t i = 0; i < sepLineLen; ++i) output += '_';
- output += "\n\n";
+ std::for_each(results.begin(), results.end(), [&](const std::wstring& str) { output += str; output += L'\n'; });
- //write log items
- const auto& entries = log.getEntries();
- for (auto iter = entries.begin(); iter != entries.end(); ++iter)
- {
- output += utfCvrtTo<Utf8String>(formatMessage(*iter));
- output += '\n';
- }
+ for (size_t i = 0; i < sepLineLen; ++i) output += L'_';
+ output += L'\n';
- return replaceCpy(output, '\n', LINE_BREAK); //don't replace line break any earlier
+ return output;
}
}
inline
-Utf8String generateLogStream(const ErrorLog& log,
- const std::wstring& jobName, //may be empty
- const std::wstring& finalStatus,
- int itemsSynced, Int64 dataSynced,
- int itemsTotal, Int64 dataTotal,
- long totalTime) //unit: [sec]
+void saveLogToFile(const SummaryInfo& summary, //throw FileError
+ const ErrorLog& log,
+ FileOutput& fileOut)
{
- return generateLogStream_impl(log, jobName, finalStatus, itemsSynced, dataSynced, itemsTotal, dataTotal, totalTime);
+ Utf8String header = utfCvrtTo<Utf8String>(generateLogHeader(summary));
+ replace(header, '\n', LINE_BREAK); //don't replace line break any earlier
+ header += LINE_BREAK; //make sure string is not empty!
+
+ fileOut.write(&*header.begin(), header.size()); //throw FileError
+
+ //write log items one after the other instead of creating one big string: memory allocation might fail; think 1 million entries!
+ for (auto iter = log.begin(); iter != log.end(); ++iter)
+ {
+ Utf8String msg = replaceCpy(utfCvrtTo<Utf8String>(formatMessage<std::wstring>(*iter)), '\n', LINE_BREAK);
+ msg += LINE_BREAK; //make sure string is not empty!
+
+ fileOut.write(&*msg.begin(), msg.size()); //throw FileError
+ }
}
inline
-void saveToLastSyncsLog(const Utf8String& logstream) //throw FileError
+void saveToLastSyncsLog(const SummaryInfo& summary, //throw FileError
+ const ErrorLog& log,
+ size_t maxBytesToWrite) //log may be *huge*, e.g. 1 million items; LastSyncs.log *must not* create performance problems!
+
{
const Zstring filename = getConfigDir() + Zstr("LastSyncs.log");
- Utf8String oldStream;
- try
- {
- oldStream = loadBinStream<Utf8String>(filename); //throw FileError, ErrorNotExisting
- }
- catch (const ErrorNotExisting&) {}
+ Utf8String newStream = utfCvrtTo<Utf8String>(generateLogHeader(summary));
+ replace(newStream, '\n', LINE_BREAK); //don't replace line break any earlier
+ newStream += LINE_BREAK;
- Utf8String newStream = logstream;
- if (!oldStream.empty())
+ //write log items one after the other instead of creating one big string: memory allocation might fail; think 1 million entries!
+ for (auto iter = log.begin(); iter != log.end(); ++iter)
{
+ newStream += replaceCpy(utfCvrtTo<Utf8String>(formatMessage<std::wstring>(*iter)), '\n', LINE_BREAK);
newStream += LINE_BREAK;
- newStream += LINE_BREAK;
- newStream += oldStream;
- }
- //limit file size: 128 kB (but do not truncate new log)
- const size_t newSize = std::min(newStream.size(), std::max<size_t>(logstream.size(), 128 * 1024));
+ if (newStream.size() > maxBytesToWrite)
+ {
+ newStream += "[...]";
+ newStream += LINE_BREAK;
+ break;
+ }
+ }
- //do not cut in the middle of a row
- auto iter = std::search(newStream.cbegin() + newSize, newStream.cend(), std::begin(LINE_BREAK), std::end(LINE_BREAK) - 1);
- if (iter != newStream.cend())
+ //fill up the rest of permitted space by appending old log
+ if (newStream.size() < maxBytesToWrite)
{
- newStream.resize(iter - newStream.cbegin());
-
- newStream += LINE_BREAK;
- newStream += "[...]";
- newStream += LINE_BREAK;
+ Utf8String oldStream;
+ try
+ {
+ oldStream = loadBinStream<Utf8String>(filename); //throw FileError, ErrorNotExisting
+ }
+ catch (const ErrorNotExisting&) {}
+
+ if (!oldStream.empty())
+ {
+ newStream += LINE_BREAK;
+ newStream += LINE_BREAK;
+ newStream += oldStream; //impliticly limited by "maxBytesToWrite"!
+
+ //truncate size if required
+ if (newStream.size() > maxBytesToWrite)
+ {
+ //but do not cut in the middle of a row
+ auto iter = std::search(newStream.cbegin() + maxBytesToWrite, newStream.cend(), std::begin(LINE_BREAK), std::end(LINE_BREAK) - 1);
+ if (iter != newStream.cend())
+ {
+ newStream.resize(iter - newStream.cbegin());
+ newStream += LINE_BREAK;
+
+ newStream += "[...]";
+ newStream += LINE_BREAK;
+ }
+ }
+ }
}
saveBinStream(filename, newStream); //throw FileError
bgstack15