From f23e5b108e71a7536337ffaaac73cac1379edd58 Mon Sep 17 00:00:00 2001 From: Stephane Janel Date: Wed, 17 Jan 2024 23:50:57 +0100 Subject: [PATCH] Use DurationToString in logs --- src/api-objects/src/tradeoptions.cpp | 10 +-- src/api/common/src/exchangeprivateapi.cpp | 5 +- src/api/exchanges/src/binanceprivateapi.cpp | 11 +-- src/api/exchanges/src/bithumbprivateapi.cpp | 5 +- src/api/exchanges/src/krakenprivateapi.cpp | 3 +- src/api/exchanges/src/upbitprivateapi.cpp | 5 +- src/engine/include/coincenteroptionsdef.hpp | 8 +- src/engine/src/coincentercommandfactory.cpp | 4 +- src/engine/src/coincentercommands.cpp | 17 ++--- src/http-request/include/besturlpicker.hpp | 8 +- .../include/invariant-request-retry.hpp | 5 +- src/http-request/src/besturlpicker.cpp | 24 +++--- src/http-request/src/curlhandle.cpp | 12 +-- .../src/prometheusmetricgateway.cpp | 4 +- src/tech/src/durationstring.cpp | 73 +++++-------------- 15 files changed, 78 insertions(+), 116 deletions(-) diff --git a/src/api-objects/src/tradeoptions.cpp b/src/api-objects/src/tradeoptions.cpp index f0090958..3bb626d4 100644 --- a/src/api-objects/src/tradeoptions.cpp +++ b/src/api-objects/src/tradeoptions.cpp @@ -1,11 +1,10 @@ #include "tradeoptions.hpp" -#include #include #include "cct_string.hpp" +#include "durationstring.hpp" #include "priceoptions.hpp" -#include "stringhelpers.hpp" #include "timedef.hpp" #include "tradedefinitions.hpp" #include "unreachable.hpp" @@ -79,10 +78,9 @@ string TradeOptions::str(bool placeRealOrderInSimulationMode) const { ret.append(", "); ret.append(tradeSyncPolicyStr()); ret.append(" mode, timeout of "); - AppendString(ret, std::chrono::duration_cast(_maxTradeTime).count()); - ret.append("s, ").append(timeoutActionStr()).append(" at timeout, min time between two price updates of "); - AppendString(ret, std::chrono::duration_cast(_minTimeBetweenPriceUpdates).count()); - ret.push_back('s'); + ret.append(DurationToString(_maxTradeTime)); + ret.append(", ").append(timeoutActionStr()).append(" at timeout, min time between two price updates of "); + ret.append(DurationToString(_minTimeBetweenPriceUpdates)); return ret; } } // namespace cct \ No newline at end of file diff --git a/src/api/common/src/exchangeprivateapi.cpp b/src/api/common/src/exchangeprivateapi.cpp index 37a3a5ab..d0e8e801 100644 --- a/src/api/common/src/exchangeprivateapi.cpp +++ b/src/api/common/src/exchangeprivateapi.cpp @@ -21,6 +21,7 @@ #include "currencycode.hpp" #include "deposit.hpp" #include "depositsconstraints.hpp" +#include "durationstring.hpp" #include "exchangebase.hpp" #include "exchangeinfo.hpp" #include "exchangename.hpp" @@ -253,9 +254,9 @@ DeliveredWithdrawInfo ExchangePrivate::withdraw(MonetaryAmount grossAmount, Exch InitiatedWithdrawInfo initiatedWithdrawInfo = launchWithdraw(grossAmount, targetExchange.queryDepositWallet(currencyCode)); Duration withdrawRefreshTime = withdrawOptions.withdrawRefreshTime(); - log::info("Withdraw {} of {} to {} initiated from {} to {}, with a periodic refresh time of {} s", + log::info("Withdraw {} of {} to {} initiated from {} to {}, with a periodic refresh time of {}", initiatedWithdrawInfo.withdrawId(), grossAmount, initiatedWithdrawInfo.receivingWallet(), exchangeName(), - targetExchange.exchangeName(), std::chrono::duration_cast(withdrawRefreshTime).count()); + targetExchange.exchangeName(), DurationToString(withdrawRefreshTime)); SentWithdrawInfo sentWithdrawInfo(currencyCode); MonetaryAmount netDeliveredAmount; diff --git a/src/api/exchanges/src/binanceprivateapi.cpp b/src/api/exchanges/src/binanceprivateapi.cpp index 9e2a772f..15468a79 100644 --- a/src/api/exchanges/src/binanceprivateapi.cpp +++ b/src/api/exchanges/src/binanceprivateapi.cpp @@ -30,6 +30,7 @@ #include "currencyexchangeflatset.hpp" #include "deposit.hpp" #include "depositsconstraints.hpp" +#include "durationstring.hpp" #include "exchangename.hpp" #include "exchangeprivateapi.hpp" #include "exchangeprivateapitypes.hpp" @@ -120,8 +121,8 @@ bool CheckErrorDoRetry(int statusCode, const json& ret, QueryDelayDir& queryDela sleepingTime = kInitialDurationQueryDelay; } queryDelay -= sleepingTime; - log::warn("Our local time is ahead of Binance server's time. Query delay modified to {} ms", - std::chrono::duration_cast(queryDelay).count()); + log::warn("Our local time is ahead of Binance server's time. Query delay modified to {}", + DurationToString(queryDelay)); // Ensure Nonce is increasing while modifying the query delay std::this_thread::sleep_for(sleepingTime); return true; @@ -136,8 +137,8 @@ bool CheckErrorDoRetry(int statusCode, const json& ret, QueryDelayDir& queryDela sleepingTime = kInitialDurationQueryDelay; } queryDelay += sleepingTime; - log::warn("Our local time is behind of Binance server's time. Query delay modified to {} ms", - std::chrono::duration_cast(queryDelay).count()); + log::warn("Our local time is behind of Binance server's time. Query delay modified to {}", + DurationToString(queryDelay)); return true; } } @@ -172,7 +173,7 @@ json PrivateQuery(CurlHandle& curlHandle, const APIKey& apiKey, HttpRequestType json ret; for (int retryPos = 0; retryPos < kNbOrderRequestsRetries; ++retryPos) { if (retryPos != 0) { - log::trace("Wait {} ms...", std::chrono::duration_cast(sleepingTime).count()); + log::trace("Wait {}...", DurationToString(sleepingTime)); std::this_thread::sleep_for(sleepingTime); sleepingTime = (3 * sleepingTime) / 2; } diff --git a/src/api/exchanges/src/bithumbprivateapi.cpp b/src/api/exchanges/src/bithumbprivateapi.cpp index c5cb5cfd..b2fce5b0 100644 --- a/src/api/exchanges/src/bithumbprivateapi.cpp +++ b/src/api/exchanges/src/bithumbprivateapi.cpp @@ -31,6 +31,7 @@ #include "currencycode.hpp" #include "deposit.hpp" #include "depositsconstraints.hpp" +#include "durationstring.hpp" #include "exchangeinfo.hpp" #include "exchangename.hpp" #include "exchangeprivateapi.hpp" @@ -975,8 +976,8 @@ InitiatedWithdrawInfo BithumbPrivate::launchWithdraw(MonetaryAmount grossAmount, static constexpr int kNbRetriesCatchWindow = 15; for (int retryPos = 0; retryPos < kNbRetriesCatchWindow && newWithdrawTrx.empty(); ++retryPos) { if (retryPos != 0) { - log::warn("Cannot retrieve just launched withdraw, retry {}/{} in {} s...", retryPos, kNbRetriesCatchWindow, - std::chrono::duration_cast(sleepingTime).count()); + log::warn("Cannot retrieve just launched withdraw, retry {}/{} in {}...", retryPos, kNbRetriesCatchWindow, + DurationToString(sleepingTime)); std::this_thread::sleep_for(sleepingTime); sleepingTime = (3 * sleepingTime) / 2; } diff --git a/src/api/exchanges/src/krakenprivateapi.cpp b/src/api/exchanges/src/krakenprivateapi.cpp index 1ff5e73d..d927cbfc 100644 --- a/src/api/exchanges/src/krakenprivateapi.cpp +++ b/src/api/exchanges/src/krakenprivateapi.cpp @@ -31,6 +31,7 @@ #include "currencyexchangeflatset.hpp" #include "deposit.hpp" #include "depositsconstraints.hpp" +#include "durationstring.hpp" #include "exchangeinfo.hpp" #include "exchangename.hpp" #include "exchangeprivateapi.hpp" @@ -99,7 +100,7 @@ std::pair PrivateQuery(CurlHandle& curlHandle, const APIK errorIt = response.find(kErrorKey)) { log::error("Kraken private API rate limit exceeded"); sleepingTime *= 2; - log::debug("Wait {} ms", std::chrono::duration_cast(sleepingTime).count()); + log::debug("Wait {}", DurationToString(sleepingTime)); std::this_thread::sleep_for(sleepingTime); // We need to update the nonce diff --git a/src/api/exchanges/src/upbitprivateapi.cpp b/src/api/exchanges/src/upbitprivateapi.cpp index db1a347e..eed75051 100644 --- a/src/api/exchanges/src/upbitprivateapi.cpp +++ b/src/api/exchanges/src/upbitprivateapi.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -33,6 +32,7 @@ #include "currencyexchangeflatset.hpp" #include "deposit.hpp" #include "depositsconstraints.hpp" +#include "durationstring.hpp" #include "exchangeinfo.hpp" #include "exchangename.hpp" #include "exchangeprivateapi.hpp" @@ -219,8 +219,7 @@ Wallet UpbitPrivate::DepositWalletFunc::operator()(CurrencyCode currencyCode) { int nbRetries = 0; do { if (nbRetries > 0) { - log::info("Waiting {} s for address to be generated...", - std::chrono::duration_cast(sleepingTime).count()); + log::info("Waiting {} for address to be generated...", DurationToString(sleepingTime)); } std::this_thread::sleep_for(sleepingTime); result = PrivateQuery(_curlHandle, _apiKey, HttpRequestType::kGet, "/v1/deposits/coin_address", postData); diff --git a/src/engine/include/coincenteroptionsdef.hpp b/src/engine/include/coincenteroptionsdef.hpp index 9337f3bc..d7a8760f 100644 --- a/src/engine/include/coincenteroptionsdef.hpp +++ b/src/engine/include/coincenteroptionsdef.hpp @@ -25,9 +25,9 @@ class CoincenterCmdLineOptionsDefinitions { static constexpr int kDefaultMonitoringPort = 9091; // Prometheus default push port static constexpr Duration kDefaultRepeatTime = TimeInS(1); - static constexpr int64_t kDefaultTradeTimeout = + static constexpr int64_t kDefaultTradeTimeoutSeconds = std::chrono::duration_cast(TradeOptions().maxTradeTime()).count(); - static constexpr int64_t kMinUpdatePriceTime = + static constexpr int64_t kMinUpdatePriceTimeSeconds = std::chrono::duration_cast(TradeOptions().minTimeBetweenPriceUpdates()).count(); static constexpr int64_t kDefaultRepeatDurationSeconds = std::chrono::duration_cast(kDefaultRepeatTime).count(); @@ -76,7 +76,7 @@ class CoincenterCmdLineOptionsDefinitions { static constexpr std::string_view kTradeTimeout1 = "Adjust trade timeout (default: "; static constexpr std::string_view kTradeTimeout2 = "s). Remaining orders will be cancelled after the timeout."; static constexpr std::string_view kTradeTimeout = - JoinStringView_v, kTradeTimeout2>; + JoinStringView_v, kTradeTimeout2>; static constexpr std::string_view kTradeUpdatePrice1 = "Set the min time allowed between two limit price updates (default: "; @@ -84,7 +84,7 @@ class CoincenterCmdLineOptionsDefinitions { "s). Avoids cancelling / placing new orders too often with high volumes which can be counter productive " "sometimes."; static constexpr std::string_view kTradeUpdatePrice = - JoinStringView_v, kTradeUpdatePrice2>; + JoinStringView_v, kTradeUpdatePrice2>; static constexpr std::string_view kSimulationMode1 = "Activates simulation mode only (default: "; static constexpr std::string_view kSimulationMode2 = TradeOptions().isSimulation() ? "true" : "false"; diff --git a/src/engine/src/coincentercommandfactory.cpp b/src/engine/src/coincentercommandfactory.cpp index fbbf9997..c7f81ab3 100644 --- a/src/engine/src/coincentercommandfactory.cpp +++ b/src/engine/src/coincentercommandfactory.cpp @@ -1,6 +1,5 @@ #include "coincentercommandfactory.hpp" -#include #include #include @@ -34,8 +33,7 @@ CoincenterCommand CoincenterCommandFactory::createOrderCommand(CoincenterCommand } CoincenterCommand ret(type); ret.setOrdersConstraints( - OrdersConstraints(market.base(), market.quote(), std::chrono::duration_cast(_cmdLineOptions.minAge), - std::chrono::duration_cast(_cmdLineOptions.maxAge), + OrdersConstraints(market.base(), market.quote(), _cmdLineOptions.minAge, _cmdLineOptions.maxAge, OrdersConstraints::OrderIdSet(StringOptionParser(_cmdLineOptions.ids).getCSVValues()))) .setExchangeNames(optionParser.parseExchanges()); return ret; diff --git a/src/engine/src/coincentercommands.cpp b/src/engine/src/coincentercommands.cpp index 30983a15..e4b5dad7 100644 --- a/src/engine/src/coincentercommands.cpp +++ b/src/engine/src/coincentercommands.cpp @@ -1,6 +1,5 @@ #include "coincentercommands.hpp" -#include #include #include #include @@ -116,22 +115,18 @@ void CoincenterCommands::addOption(const CoincenterCmdLineOptions &cmdLineOption if (cmdLineOptions.recentDepositsInfo) { optionParser = StringOptionParser(*cmdLineOptions.recentDepositsInfo); _commands.emplace_back(CoincenterCommandType::kRecentDeposits) - .setDepositsConstraints( - DepositsConstraints(optionParser.parseCurrency(StringOptionParser::FieldIs::kOptional), - std::chrono::duration_cast(cmdLineOptions.minAge), - std::chrono::duration_cast(cmdLineOptions.maxAge), - DepositsConstraints::IdSet(StringOptionParser(cmdLineOptions.ids).getCSVValues()))) + .setDepositsConstraints(DepositsConstraints( + optionParser.parseCurrency(StringOptionParser::FieldIs::kOptional), cmdLineOptions.minAge, + cmdLineOptions.maxAge, DepositsConstraints::IdSet(StringOptionParser(cmdLineOptions.ids).getCSVValues()))) .setExchangeNames(optionParser.parseExchanges()); } if (cmdLineOptions.recentWithdrawsInfo) { optionParser = StringOptionParser(*cmdLineOptions.recentWithdrawsInfo); _commands.emplace_back(CoincenterCommandType::kRecentWithdraws) - .setWithdrawsConstraints( - WithdrawsConstraints(optionParser.parseCurrency(StringOptionParser::FieldIs::kOptional), - std::chrono::duration_cast(cmdLineOptions.minAge), - std::chrono::duration_cast(cmdLineOptions.maxAge), - WithdrawsConstraints::IdSet(StringOptionParser(cmdLineOptions.ids).getCSVValues()))) + .setWithdrawsConstraints(WithdrawsConstraints( + optionParser.parseCurrency(StringOptionParser::FieldIs::kOptional), cmdLineOptions.minAge, + cmdLineOptions.maxAge, WithdrawsConstraints::IdSet(StringOptionParser(cmdLineOptions.ids).getCSVValues()))) .setExchangeNames(optionParser.parseExchanges()); } diff --git a/src/http-request/include/besturlpicker.hpp b/src/http-request/include/besturlpicker.hpp index 44a71b35..56c975e5 100644 --- a/src/http-request/include/besturlpicker.hpp +++ b/src/http-request/include/besturlpicker.hpp @@ -55,13 +55,13 @@ class BestURLPicker { : _pBaseUrls(baseUrls.data()), _responseTimeStatsPerBaseUrl(baseUrls.size()) {} struct ResponseTimeStats { - uint16_t nbRequestsDone; // when reaching max, all stats are reset to give equal chances to all base URLs - uint16_t avgResponseTime; // approximation of moving average - uint16_t avgDeviation; // approximation of moving standard deviation + uint16_t nbRequestsDone; // when reaching max, all stats are reset to give equal chances to all base URLs + uint16_t avgResponseTimeInMs; // approximation of moving average + uint16_t avgDeviationInMs; // approximation of moving standard deviation bool operator==(const ResponseTimeStats &) const noexcept = default; - uint32_t score() const { return static_cast(avgResponseTime) + avgDeviation; } + uint32_t score() const { return static_cast(avgResponseTimeInMs) + avgDeviationInMs; } }; using ResponseTimeStatsPerBaseUrl = FixedCapacityVector; diff --git a/src/http-request/include/invariant-request-retry.hpp b/src/http-request/include/invariant-request-retry.hpp index 237c58fd..6ea7e06c 100644 --- a/src/http-request/include/invariant-request-retry.hpp +++ b/src/http-request/include/invariant-request-retry.hpp @@ -11,6 +11,7 @@ #include "cct_type_traits.hpp" #include "curlhandle.hpp" #include "curloptions.hpp" +#include "durationstring.hpp" #include "timedef.hpp" #include "unreachable.hpp" @@ -50,8 +51,8 @@ class InvariantRequestRetry { do { if (nbRetries != 0) { - log::warn("Got query error: '{}', retry {}/{} after {} ms", ret.dump(), nbRetries, - _queryRetryPolicy.nbMaxRetries, std::chrono::duration_cast(sleepingTime).count()); + log::warn("Got query error: '{}', retry {}/{} after {}", ret.dump(), nbRetries, _queryRetryPolicy.nbMaxRetries, + DurationToString(sleepingTime)); std::this_thread::sleep_for(sleepingTime); sleepingTime *= _queryRetryPolicy.exponentialBackoff; } diff --git a/src/http-request/src/besturlpicker.cpp b/src/http-request/src/besturlpicker.cpp index b10fa625..e2427d7f 100644 --- a/src/http-request/src/besturlpicker.cpp +++ b/src/http-request/src/besturlpicker.cpp @@ -67,33 +67,33 @@ void BestURLPicker::storeResponseTimePerBaseURL(int8_t baseUrlPos, uint32_t resp NbRequestType nbRequestsToConsider = std::min(stats.nbRequestsDone, kMaxLastNbRequestsToConsider); // Update moving average - uint64_t sumResponseTime = static_cast(stats.avgResponseTime) * (nbRequestsToConsider - 1); + uint64_t sumResponseTime = static_cast(stats.avgResponseTimeInMs) * (nbRequestsToConsider - 1); sumResponseTime += responseTimeInMs; uint64_t newAverageResponseTime = sumResponseTime / nbRequestsToConsider; - using RTType = decltype(stats.avgResponseTime); + using RTType = decltype(stats.avgResponseTimeInMs); if (newAverageResponseTime > static_cast(std::numeric_limits::max())) { log::warn("Cannot update accurately the new average response time {} because of overflow", newAverageResponseTime); - stats.avgResponseTime = std::numeric_limits::max(); + stats.avgResponseTimeInMs = std::numeric_limits::max(); } else { - stats.avgResponseTime = static_cast(newAverageResponseTime); + stats.avgResponseTimeInMs = static_cast(newAverageResponseTime); } // Update moving deviation - uint64_t sumDeviation = static_cast(ipow(stats.avgDeviation, 2)) * (nbRequestsToConsider - 1); + uint64_t sumDeviation = static_cast(ipow(stats.avgDeviationInMs, 2)) * (nbRequestsToConsider - 1); sumDeviation += static_cast( - ipow(static_cast(stats.avgResponseTime) - static_cast(responseTimeInMs), 2)); - uint64_t newDeviationResponseTime = static_cast(std::sqrt(sumDeviation / nbRequestsToConsider)); - using DevType = decltype(stats.avgDeviation); + ipow(static_cast(stats.avgResponseTimeInMs) - static_cast(responseTimeInMs), 2)); + auto newDeviationResponseTime = static_cast(std::sqrt(sumDeviation / nbRequestsToConsider)); + using DevType = decltype(stats.avgDeviationInMs); if (newDeviationResponseTime > static_cast(std::numeric_limits::max())) { log::warn("Cannot update accurately the new deviation response time {} because of overflow", newDeviationResponseTime); - stats.avgDeviation = std::numeric_limits::max(); + stats.avgDeviationInMs = std::numeric_limits::max(); } else { - stats.avgDeviation = static_cast(newDeviationResponseTime); + stats.avgDeviationInMs = static_cast(newDeviationResponseTime); } log::debug("Response time stats for '{}': Avg: {} ms, Dev: {} ms, Nb: {} (last: {} ms)", _pBaseUrls[baseUrlPos], - stats.avgResponseTime, stats.avgDeviation, stats.nbRequestsDone, responseTimeInMs); + stats.avgResponseTimeInMs, stats.avgDeviationInMs, stats.nbRequestsDone, responseTimeInMs); } int BestURLPicker::nbRequestsDone() const { @@ -101,4 +101,4 @@ int BestURLPicker::nbRequestsDone() const { [](int sum, ResponseTimeStats stats) { return sum + stats.nbRequestsDone; }); } -} // namespace cct \ No newline at end of file +} // namespace cct diff --git a/src/http-request/src/curlhandle.cpp b/src/http-request/src/curlhandle.cpp index f66dfec5..ca21e653 100644 --- a/src/http-request/src/curlhandle.cpp +++ b/src/http-request/src/curlhandle.cpp @@ -23,6 +23,7 @@ #include "curlmetrics.hpp" #include "curloptions.hpp" #include "curlpostdata.hpp" +#include "durationstring.hpp" #include "flatkeyvaluestring.hpp" #include "httprequesttype.hpp" #include "metric.hpp" @@ -115,9 +116,8 @@ CurlHandle::CurlHandle(const BestURLPicker &bestURLPicker, AbstractMetricGateway CurlSetLogIfError(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); #endif - log::debug("Initialize CurlHandle for {} with {} ms as minimum duration between queries", - bestURLPicker.getNextBaseURL(), - std::chrono::duration_cast(_minDurationBetweenQueries).count()); + log::debug("Initialize CurlHandle for {} with {} as minimum duration between queries", + bestURLPicker.getNextBaseURL(), DurationToString(_minDurationBetweenQueries)); if (settings::IsProxyRequested(runMode)) { if (IsProxyAvailable()) { @@ -224,7 +224,7 @@ std::string_view CurlHandle::query(std::string_view endpoint, const CurlOptions if (nowTime < _lastQueryTime + _minDurationBetweenQueries) { // We should sleep a bit before performing query const Duration sleepingTime = _minDurationBetweenQueries - (nowTime - _lastQueryTime); - log::debug("Wait {} ms before performing query", std::chrono::duration_cast(sleepingTime).count()); + log::debug("Wait {} before performing query", DurationToString(sleepingTime)); std::this_thread::sleep_for(sleepingTime); _lastQueryTime = nowTime + sleepingTime; } else { @@ -247,8 +247,8 @@ std::string_view CurlHandle::query(std::string_view endpoint, const CurlOptions _pMetricGateway->add(MetricType::kCounter, MetricOperation::kIncrement, CurlMetrics::kNbRequestErrorKeys.find(opts.requestType())->second); } - log::error("Got curl error ({}), retry {}/{} after {} ms", static_cast(res), retryPos, kNbMaxRetries, - std::chrono::duration_cast(sleepingTime).count()); + log::error("Got curl error ({}), retry {}/{} after {}", static_cast(res), retryPos, kNbMaxRetries, + DurationToString(sleepingTime)); std::this_thread::sleep_for(sleepingTime); sleepingTime *= 2; } diff --git a/src/monitoring/src/prometheusmetricgateway.cpp b/src/monitoring/src/prometheusmetricgateway.cpp index b95949ae..ffe7a565 100644 --- a/src/monitoring/src/prometheusmetricgateway.cpp +++ b/src/monitoring/src/prometheusmetricgateway.cpp @@ -19,6 +19,7 @@ #include "abstractmetricgateway.hpp" #include "cct_exception.hpp" #include "cct_log.hpp" +#include "durationstring.hpp" #include "gethostname.hpp" #include "metric.hpp" #include "monitoringinfo.hpp" @@ -216,8 +217,7 @@ void PrometheusMetricGateway::flush() { auto nowTime = Clock::now(); int returnCode = _gateway.Push(); if (returnCode == kHTTPSuccessReturnCode) { - log::info("Flushed data to Prometheus in {} ms", - std::chrono::duration_cast(Clock::now() - nowTime).count()); + log::info("Flushed data to Prometheus in {}", DurationToString(Clock::now() - nowTime)); } else { log::error("Unable to push metrics to Prometheus instance - Bad return code {}", returnCode); } diff --git a/src/tech/src/durationstring.cpp b/src/tech/src/durationstring.cpp index b35ce9e6..7cbf6b2b 100644 --- a/src/tech/src/durationstring.cpp +++ b/src/tech/src/durationstring.cpp @@ -75,61 +75,28 @@ Duration ParseDuration(std::string_view durationStr) { return ret; } +template +void AdjustWithUnit(std::string_view unitStr, Duration &dur, string &ret) { + if (dur >= TimeUnitT(1)) { + auto nU = std::chrono::duration_cast(dur).count(); + AppendString(ret, nU); + ret += unitStr; + dur -= TimeUnitT(nU); + } +} + string DurationToString(Duration dur) { string ret; - if (dur >= std::chrono::years(1)) { - int64_t nbY = std::chrono::duration_cast(dur).count(); - AppendString(ret, nbY); - ret.push_back('y'); - dur -= std::chrono::years(nbY); - } - if (dur >= std::chrono::months(1)) { - int64_t nM = std::chrono::duration_cast(dur).count(); - AppendString(ret, nM); - ret.append("mon"); - dur -= std::chrono::months(nM); - } - if (dur >= std::chrono::weeks(1)) { - int64_t nbW = std::chrono::duration_cast(dur).count(); - AppendString(ret, nbW); - ret.push_back('w'); - dur -= std::chrono::weeks(nbW); - } - if (dur >= std::chrono::days(1)) { - int64_t nbD = std::chrono::duration_cast(dur).count(); - AppendString(ret, nbD); - ret.push_back('d'); - dur -= std::chrono::days(nbD); - } - if (dur >= std::chrono::hours(1)) { - int64_t nbH = std::chrono::duration_cast(dur).count(); - AppendString(ret, nbH); - ret.push_back('h'); - dur -= std::chrono::hours(nbH); - } - if (dur >= std::chrono::minutes(1)) { - int64_t nbMin = std::chrono::duration_cast(dur).count(); - AppendString(ret, nbMin); - ret.append("min"); - dur -= std::chrono::minutes(nbMin); - } - if (dur >= std::chrono::seconds(1)) { - int64_t nbS = std::chrono::duration_cast(dur).count(); - AppendString(ret, nbS); - ret.push_back('s'); - dur -= std::chrono::seconds(nbS); - } - if (dur >= std::chrono::milliseconds(1)) { - int64_t nbMs = std::chrono::duration_cast(dur).count(); - AppendString(ret, nbMs); - ret.append("ms"); - dur -= std::chrono::milliseconds(nbMs); - } - if (dur >= std::chrono::microseconds(1)) { - int64_t nbUs = std::chrono::duration_cast(dur).count(); - AppendString(ret, nbUs); - ret.append("us"); - } + + AdjustWithUnit("y", dur, ret); + AdjustWithUnit("mon", dur, ret); + AdjustWithUnit("w", dur, ret); + AdjustWithUnit("d", dur, ret); + AdjustWithUnit("h", dur, ret); + AdjustWithUnit("min", dur, ret); + AdjustWithUnit("s", dur, ret); + AdjustWithUnit("ms", dur, ret); + AdjustWithUnit("us", dur, ret); return ret; }