/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include using namespace apache::thrift; using namespace static_reflection::demo; struct metrics_client { template void add(const Metric& name, const Value& value) { metrics_[name] += value; } void report() { for (const auto& i : metrics_) { std::cout << i.first << ": " << i.second << '\n'; } } private: std::unordered_map metrics_; }; // dynamic // struct export_metric_dynamic { template void operator()( fatal::indexed, metrics_client& sink, T const& metrics, const std::string& prefix) const { const auto key = prefix + fatal::z_data(); const auto& value = typename Member::getter{}(metrics); sink.add(key, value); } }; std::string const kPrefix = "my_app."; template void export_metrics_dynamic(metrics_client& sink, T const& metrics) { using info = reflect_struct; fatal::foreach( export_metric_dynamic(), sink, metrics, folly::to( kPrefix, fatal::z_data(), '.')); } // static // struct export_metric_static { FATAL_S(prefix, "my_app"); FATAL_S(dot, "."); template void operator()( fatal::indexed, metrics_client& sink, T const& metrics) const { using info = reflect_struct; using key = fatal:: cat; const auto& value = typename Member::getter{}(metrics); sink.add(fatal::z_data(), value); } }; template void export_metrics_static(metrics_client& sink, T const& metrics) { fatal::foreach::members>( export_metric_static(), sink, metrics); } // driver // int main(int argc, char** argv) { folly::init(&argc, &argv); metrics_client sink; host_info metric; *metric.cpu_ref() = 1; *metric.memory_ref() = 12; *metric.disk_ref() = 1234; *metric.network_bytes_sent_ref() = 123; *metric.network_bytes_received_ref() = 321; *metric.network_retransmits_ref() = 2; *metric.network_connection_reset_ref() = 3; *metric.network_packets_dropped_ref() = 1; int iterations = argc > 2 ? atoi(argv[2]) : 1000000; // try running this binary through `perf stat` for both versions if (argc > 1 && argv[1] == std::string("dynamic")) { std::cout << "dynamic version, " << iterations << " iterations\n"; while (iterations--) { export_metrics_dynamic(sink, metric); } } else { std::cout << "static version, " << iterations << " iterations\n"; while (iterations--) { export_metrics_static(sink, metric); } } sink.report(); return 0; }