|
34 | 34 | #include <thread> |
35 | 35 | #include <memory> |
36 | 36 | #include <functional> |
| 37 | +#include <queue> |
| 38 | +#include <mutex> |
37 | 39 |
|
38 | 40 | #include "InfoLoggerMessageHelper.h" |
39 | 41 | #include "Common/LineBuffer.h" |
@@ -167,6 +169,26 @@ int infoLoggerLogDebug(InfoLoggerHandle handle, const char* message, ...) |
167 | 169 | return err; |
168 | 170 | } |
169 | 171 |
|
| 172 | + |
| 173 | +// function to convert severities to a priority number (high priority = small number) |
| 174 | +int getIdFromSeverity(InfoLogger::Severity s) { |
| 175 | + switch (s) { |
| 176 | + case InfoLogger::Severity::Fatal : |
| 177 | + return 1; |
| 178 | + case InfoLogger::Severity::Error : |
| 179 | + return 2; |
| 180 | + case InfoLogger::Severity::Warning : |
| 181 | + return 3; |
| 182 | + case InfoLogger::Severity::Info : |
| 183 | + return 4; |
| 184 | + case InfoLogger::Severity::Debug : |
| 185 | + return 5; |
| 186 | + default: |
| 187 | + return 6; |
| 188 | + } |
| 189 | +} |
| 190 | + |
| 191 | + |
170 | 192 | ///////////////////////////////////////////////////////// |
171 | 193 |
|
172 | 194 | namespace AliceO2 |
@@ -420,7 +442,18 @@ class InfoLogger::Impl |
420 | 442 | bool filterDiscardFileEnabled = false; // when set, discarded messages go to file |
421 | 443 | bool filterDiscardFileIgnoreDebug = false; // when set, debug messages even when discarded and filterDiscardFileEnabled=true do not go to file |
422 | 444 | SimpleLog filterDiscardFile; // file object where to save discarded messages |
| 445 | + |
| 446 | + // history |
| 447 | + unsigned int historyMessagesToKeep = 0; |
| 448 | + bool historyRotate = false; |
| 449 | + int historyFilterSeverity = -1; |
| 450 | + int historyFilterLevel = -1; |
| 451 | + std::queue<std::string> historyMessages; // messages currently in history queue |
| 452 | + std::mutex historyMutex; // lock to avoid concurrent calls on history functions |
423 | 453 |
|
| 454 | + // error code conversion table |
| 455 | + std::vector<std::pair<int, std::string>> errorCodesTable; // first: error code, second: description |
| 456 | + |
424 | 457 | // message flood prevention |
425 | 458 | // constants |
426 | 459 | bool flood_protection = 1; // if set, flood protection mechanism enabled |
@@ -787,6 +820,32 @@ int InfoLogger::Impl::pushMessage(const InfoLoggerMessageOption& options, const |
787 | 820 | msgHelper.MessageToText(&msg, buffer, sizeof(buffer), InfoLoggerMessageHelper::Format::Debug); |
788 | 821 | puts(buffer); |
789 | 822 | } |
| 823 | + |
| 824 | + // keep history |
| 825 | + std::unique_lock<std::mutex> lock(historyMutex); |
| 826 | + if (historyMessagesToKeep > 0) { |
| 827 | + if (historyRotate || (historyMessagesToKeep > historyMessages.size())) { |
| 828 | + if ((getIdFromSeverity(options.severity) <= historyFilterSeverity) && (options.level <= historyFilterLevel)) { |
| 829 | + std::string summary; |
| 830 | + summary += "code "+ std::to_string(options.errorCode); |
| 831 | + if (options.errorCode != undefinedMessageOption.errorCode) { |
| 832 | + for(const auto &p: errorCodesTable) { |
| 833 | + if (p.first == options.errorCode) { |
| 834 | + summary += " : " + p.second; |
| 835 | + break; |
| 836 | + } |
| 837 | + } |
| 838 | + summary += " - "; |
| 839 | + } |
| 840 | + summary += messageBody; |
| 841 | + historyMessages.push(std::move(summary)); |
| 842 | + if (historyRotate && (historyMessagesToKeep > historyMessages.size())) { |
| 843 | + historyMessages.pop(); |
| 844 | + } |
| 845 | + } |
| 846 | + } |
| 847 | + } |
| 848 | + |
790 | 849 | return 0; |
791 | 850 | } |
792 | 851 |
|
@@ -1282,6 +1341,37 @@ void InfoLogger::resetMessageCount() { |
1282 | 1341 | mPimpl->resetMessageCount(); |
1283 | 1342 | } |
1284 | 1343 |
|
| 1344 | +void InfoLogger::historyReset(unsigned int messagesToKeep, bool rotate, InfoLogger::Severity filterSeverity, InfoLogger::Level filterLevel) { |
| 1345 | + std::unique_lock<std::mutex> lock(mPimpl->historyMutex); |
| 1346 | + mPimpl->historyMessagesToKeep = messagesToKeep; |
| 1347 | + mPimpl->historyRotate = rotate; |
| 1348 | + mPimpl->historyFilterSeverity = getIdFromSeverity(filterSeverity); |
| 1349 | + mPimpl->historyFilterLevel = (int)filterLevel; |
| 1350 | + mPimpl->historyMessages = {}; // clear queue |
| 1351 | +} |
| 1352 | + |
| 1353 | +void InfoLogger::historyGetSummary(std::vector<std::string> &summary) { |
| 1354 | + std::unique_lock<std::mutex> lock(mPimpl->historyMutex); |
| 1355 | + summary.clear(); |
| 1356 | + summary.reserve(mPimpl->historyMessages.size()); |
| 1357 | + while (!mPimpl->historyMessages.empty()) |
| 1358 | + { |
| 1359 | + summary.push_back(std::move(mPimpl->historyMessages.front())); |
| 1360 | + mPimpl->historyMessages.pop(); |
| 1361 | + } |
| 1362 | +} |
| 1363 | + |
| 1364 | +void InfoLogger::registerErrorCodes(const std::vector<std::pair<int, std::string>> errorCodes, bool clear) { |
| 1365 | + std::unique_lock<std::mutex> lock(mPimpl->historyMutex); |
| 1366 | + if (clear) { |
| 1367 | + mPimpl->errorCodesTable.clear(); |
| 1368 | + } |
| 1369 | + for(const auto &c: errorCodes) { |
| 1370 | + mPimpl->errorCodesTable.push_back({c.first, c.second}); |
| 1371 | + } |
| 1372 | +} |
| 1373 | + |
| 1374 | + |
1285 | 1375 | // end of namespace |
1286 | 1376 | } // namespace InfoLogger |
1287 | 1377 | } // namespace AliceO2 |
|
0 commit comments