diff --git a/src/api_server.cc b/src/api_server.cc index 8d8f9776..6e6fbafb 100644 --- a/src/api_server.cc +++ b/src/api_server.cc @@ -70,7 +70,6 @@ class MetadataReporter { ~MetadataReporter(); private: - using seconds = std::chrono::duration; // Metadata reporter. void ReportMetadata(); @@ -83,7 +82,7 @@ class MetadataReporter { Environment environment_; OAuth2 auth_; // The reporting period in seconds. - seconds period_; + time::seconds period_; std::thread reporter_thread_; }; @@ -166,7 +165,7 @@ void MetadataReporter::ReportMetadata() { LOG(INFO) << "Metadata reporter started"; // Wait for the first collection to complete. // TODO: Come up with a more robust synchronization mechanism. - std::this_thread::sleep_for(std::chrono::seconds(3)); + std::this_thread::sleep_for(time::seconds(3)); // TODO: Do we need to be able to stop this? while (true) { if (agent_->config_.VerboseLogging()) { @@ -271,8 +270,8 @@ void MetadataReporter::SendMetadata( {"rawContentVersion", json::string(metadata.version)}, {"rawContent", std::move(metadata.metadata)}, {"state", json::string(metadata.is_deleted ? "DELETED" : "ACTIVE")}, - {"createTime", json::string(rfc3339::ToString(metadata.created_at))}, - {"collectTime", json::string(rfc3339::ToString(metadata.collected_at))}, + {"createTime", json::string(time::rfc3339::ToString(metadata.created_at))}, + {"collectTime", json::string(time::rfc3339::ToString(metadata.collected_at))}, }); // TODO: This is probably all kinds of inefficient... const int size = metadata_entry->ToString().size(); @@ -322,8 +321,8 @@ void MetadataAgent::UpdateMetadata(const MonitoredResource& resource, LOG(INFO) << "Updating metadata map " << resource << "->{" << "version: " << entry.version << ", " << "is_deleted: " << entry.is_deleted << ", " - << "created_at: " << rfc3339::ToString(entry.created_at) << ", " - << "collected_at: " << rfc3339::ToString(entry.collected_at) + << "created_at: " << time::rfc3339::ToString(entry.created_at) << ", " + << "collected_at: " << time::rfc3339::ToString(entry.collected_at) << ", " << "metadata: " << *entry.metadata << ", " << "ignore: " << entry.ignore @@ -359,9 +358,9 @@ void MetadataAgent::PurgeDeletedEntries() { LOG(INFO) << "Purging metadata entry " << resource << "->{" << "version: " << entry.version << ", " << "is_deleted: " << entry.is_deleted << ", " - << "created_at: " << rfc3339::ToString(entry.created_at) + << "created_at: " << time::rfc3339::ToString(entry.created_at) << ", " - << "collected_at: " << rfc3339::ToString(entry.collected_at) + << "collected_at: " << time::rfc3339::ToString(entry.collected_at) << ", " << "metadata: " << *entry.metadata << ", " << "ignore: " << entry.ignore diff --git a/src/api_server.h b/src/api_server.h index aa704ee7..5ef4e97f 100644 --- a/src/api_server.h +++ b/src/api_server.h @@ -27,6 +27,7 @@ #include "configuration.h" #include "json.h" #include "resource.h" +#include "time.h" namespace google { @@ -37,7 +38,7 @@ class MetadataApiServer; class MetadataReporter; // A timestamp type. -using Timestamp = std::chrono::time_point; +using Timestamp = time_point; // Stores the metadata mapping and runs the metadata tasks. class MetadataAgent { diff --git a/src/docker.cc b/src/docker.cc index 39a4ece2..3c07b81c 100644 --- a/src/docker.cc +++ b/src/docker.cc @@ -83,7 +83,7 @@ MetadataUpdater::ResourceMetadata DockerReader::GetContainerMetadata( const std::string created_str = container_desc->Get("Created"); - Timestamp created_at = rfc3339::FromString(created_str); + Timestamp created_at = time::rfc3339::FromString(created_str); const json::Object* state = container_desc->Get("State"); bool is_deleted = state->Get("Dead"); diff --git a/src/kubernetes.cc b/src/kubernetes.cc index b4bbe351..6c39cafb 100644 --- a/src/kubernetes.cc +++ b/src/kubernetes.cc @@ -101,7 +101,7 @@ MetadataUpdater::ResourceMetadata KubernetesReader::GetNodeMetadata( const std::string node_name = metadata->Get("name"); const std::string created_str = metadata->Get("creationTimestamp"); - Timestamp created_at = rfc3339::FromString(created_str); + Timestamp created_at = time::rfc3339::FromString(created_str); const MonitoredResource k8s_node("k8s_node", { {"cluster_name", cluster_name}, @@ -203,11 +203,11 @@ MetadataUpdater::ResourceMetadata KubernetesReader::GetPodMetadata( const std::string pod_id = metadata->Get("uid"); const std::string created_str = metadata->Get("creationTimestamp"); - Timestamp created_at = rfc3339::FromString(created_str); + Timestamp created_at = time::rfc3339::FromString(created_str); const json::Object* status = pod->Get("status"); const std::string started_str = status->Get("startTime"); - Timestamp started_at = rfc3339::FromString(started_str); + Timestamp started_at = time::rfc3339::FromString(started_str); const MonitoredResource k8s_pod("k8s_pod", { {"cluster_name", cluster_name}, @@ -261,7 +261,7 @@ MetadataUpdater::ResourceMetadata KubernetesReader::GetContainerMetadata( const std::string pod_id = metadata->Get("uid"); const std::string created_str = metadata->Get("creationTimestamp"); - Timestamp created_at = rfc3339::FromString(created_str); + Timestamp created_at = time::rfc3339::FromString(created_str); const json::Object* labels; if (!metadata->Has("labels")) { labels = nullptr; diff --git a/src/logging.cc b/src/logging.cc index 19eb7a2d..d4d5977f 100644 --- a/src/logging.cc +++ b/src/logging.cc @@ -30,7 +30,7 @@ Logger::Logger(const char* file, int line, Severity severity, LogStream* stream) { const std::time_t now_c = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - std::tm local_time = safe_localtime(&now_c); + std::tm local_time = time::safe_localtime(&now_c); // GCC 4.x does not implement std::put_time. Sigh. char time_val[20]; std::strftime(time_val, sizeof(time_val), "%m%d %H:%M:%S ", &local_time); diff --git a/src/oauth2.cc b/src/oauth2.cc index 50ef1eab..6de64e6a 100644 --- a/src/oauth2.cc +++ b/src/oauth2.cc @@ -32,6 +32,7 @@ #include "http_common.h" #include "json.h" #include "logging.h" +#include "time.h" namespace http = boost::network::http; @@ -138,13 +139,6 @@ std::string Sign(const std::string& data, const PKey& pkey) { return std::string(reinterpret_cast(result.get()), actual_result_size); } -// TODO: Move this to the time library? -double SecondsSinceEpoch( - const std::chrono::time_point& t) { - return std::chrono::duration_cast( - t.time_since_epoch()).count(); -} - } json::value OAuth2::ComputeTokenFromCredentials() const { @@ -209,8 +203,8 @@ json::value OAuth2::ComputeTokenFromCredentials() const { {"iss", json::string(service_account_email)}, {"scope", json::string("https://www.googleapis.com/auth/monitoring")}, {"aud", json::string("https://www.googleapis.com/oauth2/v3/token")}, - {"iat", json::number(SecondsSinceEpoch(now))}, - {"exp", json::number(SecondsSinceEpoch(exp))}, + {"iat", json::number(time::SecondsSinceEpoch(now))}, + {"exp", json::number(time::SecondsSinceEpoch(exp))}, }); if (environment_.config().VerboseLogging()) { LOG(INFO) << "claim_set = " << claim_set_object->ToString(); diff --git a/src/oauth2.h b/src/oauth2.h index 8711d5e0..1ac3a042 100644 --- a/src/oauth2.h +++ b/src/oauth2.h @@ -17,12 +17,12 @@ #define OAUTH2_H_ #include -#include #include #include #include "environment.h" #include "json.h" +#include "time.h" namespace google { @@ -41,7 +41,7 @@ class OAuth2 { const Environment& environment_; std::string auth_header_value_; - std::chrono::time_point token_expiration_; + time_point token_expiration_; }; template diff --git a/src/time.cc b/src/time.cc index 687fad8c..805c46cb 100644 --- a/src/time.cc +++ b/src/time.cc @@ -26,6 +26,8 @@ namespace google { +namespace time { + namespace rfc3339 { namespace { @@ -44,15 +46,16 @@ const int kUtcOffset = UTCOffset(); } -std::string ToString(const std::chrono::system_clock::time_point& t) { +std::string ToString(const time_point& t) { std::stringstream out; - const std::time_t time = std::chrono::system_clock::to_time_t(t); + const std::chrono::system_clock::time_point t_sec = + std::chrono::time_point_cast(t); + const std::time_t time = std::chrono::system_clock::to_time_t(t_sec); std::tm utc_time = safe_gmtime(&time); // GCC 4.x does not implement std::put_time. Sigh. char dt[64]; std::strftime(dt, sizeof(dt), "%Y-%m-%dT%H:%M:%S", &utc_time); - std::chrono::time_point - t_ns = std::chrono::time_point_cast(t); + time_point t_ns = std::chrono::time_point_cast(t); std::chrono::time_point t_s = std::chrono::time_point_cast(t_ns); const std::chrono::nanoseconds ns = t_ns - t_s; @@ -60,32 +63,32 @@ std::string ToString(const std::chrono::system_clock::time_point& t) { return out.str(); } -std::chrono::system_clock::time_point FromString(const std::string& s) { +time_point FromString(const std::string& s) { std::tm tm; char* const end = strptime(s.c_str(), "%Y-%m-%dT%H:%M:%S", &tm); if (end == nullptr || !std::isdigit(*(end - 2))) { // TODO: Invalid time format. - return std::chrono::system_clock::time_point(); + return time_point(); } char* zone; if (*end == '.') { (void)std::strtol(end + 1, &zone, 10); if (zone <= end + 1) { // TODO: Missing nanoseconds. - return std::chrono::system_clock::time_point(); + return time_point(); } } else { zone = end; } if (*zone != 'Z' || *(zone+1) != '\0') { // TODO: Invalid timezone. - return std::chrono::system_clock::time_point(); + return time_point(); } char* d_end; double seconds = std::strtod(end - 2, &d_end); if (d_end != zone) { // TODO: Internal error. - return std::chrono::system_clock::time_point(); + return time_point(); } static_assert(sizeof(long) == 8, "long is too small"); // Truncate to 9 digits by rounding to 10 and discarding the last one. @@ -94,10 +97,8 @@ std::chrono::system_clock::time_point FromString(const std::string& s) { tm.tm_isdst = 0; const std::time_t local_time = std::mktime(&tm); const std::time_t utc_time = local_time + kUtcOffset; - std::chrono::system_clock::time_point sec = - std::chrono::system_clock::from_time_t(utc_time); - return std::chrono::time_point_cast( - sec + std::chrono::nanoseconds(ns)); + time_point sec = std::chrono::system_clock::from_time_t(utc_time); + return sec + std::chrono::nanoseconds(ns); } } @@ -120,3 +121,5 @@ std::tm safe_gmtime(const std::time_t* t) { } } + +} diff --git a/src/time.h b/src/time.h index 1a721740..95939f47 100644 --- a/src/time.h +++ b/src/time.h @@ -22,11 +22,23 @@ namespace google { +using time_point = std::chrono::time_point; + +namespace time { + +using seconds = std::chrono::duration; + +inline double SecondsSinceEpoch(const time_point& t) { + return std::chrono::duration_cast( + t.time_since_epoch()).count(); +} + namespace rfc3339 { // Time conversions. -std::string ToString(const std::chrono::system_clock::time_point& t); -std::chrono::system_clock::time_point FromString(const std::string& s); +std::string ToString(const time_point& t); +time_point FromString(const std::string& s); } @@ -36,4 +48,6 @@ std::tm safe_gmtime(const std::time_t* t); } +} + #endif // TIME_H_ diff --git a/src/updater.cc b/src/updater.cc index e7593c5e..d8b1f673 100644 --- a/src/updater.cc +++ b/src/updater.cc @@ -56,7 +56,7 @@ PollingMetadataUpdater::~PollingMetadataUpdater() { } bool PollingMetadataUpdater::ValidateConfiguration() const { - return period_ >= seconds::zero(); + return period_ >= time::seconds::zero(); } void PollingMetadataUpdater::StartUpdater() { @@ -64,7 +64,7 @@ void PollingMetadataUpdater::StartUpdater() { if (config().VerboseLogging()) { LOG(INFO) << "Timer locked"; } - if (period_ > seconds::zero()) { + if (period_ > time::seconds::zero()) { reporter_thread_ = std::thread(&PollingMetadataUpdater::PollForMetadata, this); } @@ -100,7 +100,7 @@ void PollingMetadataUpdater::PollForMetadata() { } if (config().VerboseLogging()) { LOG(INFO) << " Timer unlock timed out after " - << std::chrono::duration_cast(now - start).count() + << std::chrono::duration_cast(now - start).count() << "s (good)"; } start = now; diff --git a/src/updater.h b/src/updater.h index ff013d72..84398b4f 100644 --- a/src/updater.h +++ b/src/updater.h @@ -18,7 +18,6 @@ //#include "config.h" -#include #include #include #include @@ -27,6 +26,7 @@ #include "api_server.h" #include "resource.h" +#include "time.h" namespace google { @@ -107,12 +107,11 @@ class PollingMetadataUpdater : public MetadataUpdater { void StopUpdater(); private: - using seconds = std::chrono::duration; // Metadata poller. void PollForMetadata(); // The polling period in seconds. - seconds period_; + time::seconds period_; // The function to actually query for metadata. std::function()> query_metadata_; diff --git a/test/time_unittest.cc b/test/time_unittest.cc index cc478b1a..4633dc29 100644 --- a/test/time_unittest.cc +++ b/test/time_unittest.cc @@ -6,154 +6,153 @@ using namespace google; namespace { TEST(TimeTest, EpochToString) { - const std::chrono::system_clock::time_point epoch; + const time_point epoch; EXPECT_EQ( "1970-01-01T00:00:00.000000000Z", - rfc3339::ToString(epoch) + time::rfc3339::ToString(epoch) ); } TEST(TimeTest, RoundtripViaTimePoint) { - const std::chrono::system_clock::time_point t = - rfc3339::FromString("2018-03-03T01:23:45.678901234Z"); + const time_point t = + time::rfc3339::FromString("2018-03-03T01:23:45.678901234Z"); EXPECT_EQ( "2018-03-03T01:23:45.678901234Z", - rfc3339::ToString(t) + time::rfc3339::ToString(t) ); } TEST(TimeTest, RoundtripViaString) { - const std::chrono::system_clock::time_point t = - std::chrono::system_clock::now(); + const time_point t = std::chrono::system_clock::now(); EXPECT_EQ( t, - rfc3339::FromString(rfc3339::ToString(t)) + time::rfc3339::FromString(time::rfc3339::ToString(t)) ); } TEST(TimeTest, FromStringNoNanos) { - const std::chrono::system_clock::time_point t = - rfc3339::FromString("2018-03-03T01:23:45Z"); + const time_point t = + time::rfc3339::FromString("2018-03-03T01:23:45Z"); EXPECT_EQ( "2018-03-03T01:23:45.000000000Z", - rfc3339::ToString(t) + time::rfc3339::ToString(t) ); } TEST(TimeTest, FromStringFewerDigits) { - const std::chrono::system_clock::time_point t = - rfc3339::FromString("2018-03-03T01:23:45.6789Z"); + const time_point t = + time::rfc3339::FromString("2018-03-03T01:23:45.6789Z"); EXPECT_EQ( "2018-03-03T01:23:45.678900000Z", - rfc3339::ToString(t) + time::rfc3339::ToString(t) ); } TEST(TimeTest, FromStringMoreDigits) { - const std::chrono::system_clock::time_point t = - rfc3339::FromString("2018-03-03T01:23:45.67890123456789Z"); + const time_point t = + time::rfc3339::FromString("2018-03-03T01:23:45.67890123456789Z"); EXPECT_EQ( "2018-03-03T01:23:45.678901234Z", - rfc3339::ToString(t) + time::rfc3339::ToString(t) ); } TEST(TimeTest, FromStringLargeNanos) { - const std::chrono::system_clock::time_point t = - rfc3339::FromString("2018-03-03T01:23:45.9876543210987Z"); + const time_point t = + time::rfc3339::FromString("2018-03-03T01:23:45.9876543210987Z"); EXPECT_EQ( "2018-03-03T01:23:45.987654321Z", - rfc3339::ToString(t) + time::rfc3339::ToString(t) ); } TEST(TimeTest, FromStringPositiveNanos) { - const std::chrono::system_clock::time_point t = - rfc3339::FromString("2018-03-03T01:23:45.+678901234Z"); + const time_point t = + time::rfc3339::FromString("2018-03-03T01:23:45.+678901234Z"); EXPECT_EQ( "1970-01-01T00:00:00.000000000Z", - rfc3339::ToString(t) + time::rfc3339::ToString(t) ); } TEST(TimeTest, FromStringNegativeNanos) { - const std::chrono::system_clock::time_point t = - rfc3339::FromString("2018-03-03T01:23:45.-678901234Z"); + const time_point t = + time::rfc3339::FromString("2018-03-03T01:23:45.-678901234Z"); EXPECT_EQ( "1970-01-01T00:00:00.000000000Z", - rfc3339::ToString(t) + time::rfc3339::ToString(t) ); } TEST(TimeTest, FromStringPositiveSeconds) { - const std::chrono::system_clock::time_point t = - rfc3339::FromString("2018-03-03T01:23:+4.567890123Z"); + const time_point t = + time::rfc3339::FromString("2018-03-03T01:23:+4.567890123Z"); EXPECT_EQ( "1970-01-01T00:00:00.000000000Z", - rfc3339::ToString(t) + time::rfc3339::ToString(t) ); } TEST(TimeTest, FromStringNegativeSeconds) { - const std::chrono::system_clock::time_point t = - rfc3339::FromString("2018-03-03T01:23:-4.567890123Z"); + const time_point t = + time::rfc3339::FromString("2018-03-03T01:23:-4.567890123Z"); EXPECT_EQ( "1970-01-01T00:00:00.000000000Z", - rfc3339::ToString(t) + time::rfc3339::ToString(t) ); } TEST(TimeTest, FromStringHexSeconds) { - const std::chrono::system_clock::time_point t = - rfc3339::FromString("2018-03-03T01:23:0x45.678901234Z"); + const time_point t = + time::rfc3339::FromString("2018-03-03T01:23:0x45.678901234Z"); EXPECT_EQ( "1970-01-01T00:00:00.000000000Z", - rfc3339::ToString(t) + time::rfc3339::ToString(t) ); } TEST(TimeTest, FromStringInfSeconds) { - const std::chrono::system_clock::time_point t1 = - rfc3339::FromString("2018-03-03T01:23:+infZ"); + const time_point t1 = + time::rfc3339::FromString("2018-03-03T01:23:+infZ"); EXPECT_EQ( "1970-01-01T00:00:00.000000000Z", - rfc3339::ToString(t1) + time::rfc3339::ToString(t1) ); - const std::chrono::system_clock::time_point t2 = - rfc3339::FromString("2018-03-03T01:23:-infZ"); + const time_point t2 = + time::rfc3339::FromString("2018-03-03T01:23:-infZ"); EXPECT_EQ( "1970-01-01T00:00:00.000000000Z", - rfc3339::ToString(t2) + time::rfc3339::ToString(t2) ); - const std::chrono::system_clock::time_point t3 = - rfc3339::FromString("2018-03-03T01:23:+nanZ"); + const time_point t3 = + time::rfc3339::FromString("2018-03-03T01:23:+nanZ"); EXPECT_EQ( "1970-01-01T00:00:00.000000000Z", - rfc3339::ToString(t3) + time::rfc3339::ToString(t3) ); - const std::chrono::system_clock::time_point t4 = - rfc3339::FromString("2018-03-03T01:23:-nanZ"); + const time_point t4 = + time::rfc3339::FromString("2018-03-03T01:23:-nanZ"); EXPECT_EQ( "1970-01-01T00:00:00.000000000Z", - rfc3339::ToString(t4) + time::rfc3339::ToString(t4) ); } TEST(TimeTest, FromStringTooManySeconds) { - const std::chrono::system_clock::time_point t = - rfc3339::FromString("2018-03-03T01:23:1045.678901234Z"); + const time_point t = + time::rfc3339::FromString("2018-03-03T01:23:1045.678901234Z"); EXPECT_EQ( "1970-01-01T00:00:00.000000000Z", - rfc3339::ToString(t) + time::rfc3339::ToString(t) ); } TEST(TimeTest, FromStringScientificSeconds) { - const std::chrono::system_clock::time_point t = - rfc3339::FromString("2018-03-03T01:23:45e+0Z"); + const time_point t = + time::rfc3339::FromString("2018-03-03T01:23:45e+0Z"); EXPECT_EQ( "1970-01-01T00:00:00.000000000Z", - rfc3339::ToString(t) + time::rfc3339::ToString(t) ); }