218 #ifndef zakero_Profiler_h
219 #define zakero_Profiler_h
223 #include <experimental/source_location>
231 #if defined(ZAKERO_PROFILER_ENABLE)
265 #define ZAKERO_PROFILER_INIT(output_) \
266 zakero::Profiler::init(output_, {});
310 #define ZAKERO_PROFILER_INIT_METADATA(output_, meta_data_) \
311 zakero::Profiler::init(output_, meta_data_);
359 #define ZAKERO_PROFILER_ACTIVATE \
360 zakero::Profiler::activate();
369 #define ZAKERO_PROFILER_DEACTIVATE \
370 zakero::Profiler::deactivate();
383 #define ZAKERO_CONCAT_(thing_1_, thing_2_) thing_1_ ## thing_2_
405 #define ZAKERO_CONCAT(thing_1_, thing_2_) ZAKERO_CONCAT_(thing_1_, thing_2_)
421 #define ZAKERO_PROFILER_UNIQUE(name_) ZAKERO_CONCAT(name_, __LINE__)
463 #define ZAKERO_PROFILER_DURATION(category_, name_) \
464 zakero::Profiler::Duration ZAKERO_PROFILER_UNIQUE(zakero_profiler_duration_) \
467 , std::experimental::source_location::current() \
482 #define ZAKERO_PROFILER_INSTANT(category_, name_) \
484 zakero::Profiler::Instant ZAKERO_PROFILER_UNIQUE(zakero_profiler_instant_) \
487 , std::experimental::source_location::current() \
493 #define ZAKERO_PROFILER_INIT(output_)
494 #define ZAKERO_PROFILER_INIT_METADATA(output_, meta_data_)
495 #define ZAKERO_PROFILER_ACTIVATE
496 #define ZAKERO_PROFILER_DEACTIVATE
497 #define ZAKERO_PROFILER_DURATION(category_, name_)
498 #define ZAKERO_PROFILER_INSTANT(category_, name_)
503 std::chrono::duration_cast<std::chrono::microseconds>( \
504 std::chrono::steady_clock::now().time_since_epoch() \
509 #if defined(ZAKERO__DOXYGEN_DEFINE_DOCS)
523 #define ZAKERO_PROFILER_ENABLE
536 #define ZAKERO_PROFILER_IMPLEMENTATION
549 using MetaData = std::map<std::string, std::string>;
553 std::string category;
555 std::experimental::source_location location;
556 std::chrono::microseconds::rep time_stamp;
557 std::thread::id thread_id;
561 Data(
const char,
const std::string&,
const std::string&,
const std::experimental::source_location&) noexcept;
565 :
public zakero::Profiler::Data
569 Duration(
const std::string&,
const std::string&,
const std::experimental::source_location&) noexcept;
570 ~Duration() noexcept;
574 :
public zakero::Profiler::Data
576 Instant(
const std::string&,
const std::string&,
const std::experimental::source_location&) noexcept;
580 ~Profiler() noexcept;
582 static void init(std::ostream&, zakero::Profiler::MetaData) noexcept;
583 static void init(std::string, zakero::Profiler::MetaData) noexcept;
585 static void activate() noexcept;
586 static void deactivate() noexcept;
588 static void report(
const zakero::Profiler::Data&) noexcept;
591 std::ostream* stream;
592 std::ofstream file_output;
600 #if defined (ZAKERO_PROFILER_IMPLEMENTATION)
603 #include <sys/types.h>
605 #define ZAKERO_PROFILER_PID getpid()
607 #define ZAKERO_PROFILER_PID -1
612 zakero::Profiler zakero_profiler;
655 Profiler::Profiler() noexcept
668 Profiler::~Profiler() noexcept
670 (*stream) <<
"]}" << std::endl;
672 if(file_output.is_open())
693 void zakero::Profiler::init(std::string file_name
694 , zakero::Profiler::MetaData meta_data
697 if(zakero_profiler.stream !=
nullptr)
702 zakero_profiler.file_output.open(file_name);
704 init(zakero_profiler.file_output, meta_data);
718 void zakero::Profiler::init(std::ostream& output_stream
719 , zakero::Profiler::MetaData meta_data
722 if(zakero_profiler.stream !=
nullptr)
727 zakero_profiler.stream = &output_stream;
730 if(meta_data.contains(
"date") ==
false)
732 std::time_t time = std::chrono::system_clock::to_time_t(
733 std::chrono::system_clock::now()
737 std::strftime(buf,
sizeof(buf),
"%F %T", std::localtime(&time));
739 meta_data[
"date"] = buf;
742 if(meta_data.contains(
"traceEvents"))
744 meta_data.erase(
"traceEvents");
747 meta_data[
"displayTimeUnit"] =
"ms";
749 (*zakero_profiler.stream) <<
"{";
751 for(
const auto& iter : meta_data)
753 (*zakero_profiler.stream) <<
"\"" << iter.first <<
"\":\"" << iter.second <<
"\",";
756 (*zakero_profiler.stream) <<
"\"traceEvents\":[{}\n";
766 void zakero::Profiler::activate() noexcept
768 zakero_profiler.is_active =
true;
781 void zakero::Profiler::deactivate() noexcept
783 zakero_profiler.is_active =
false;
792 void Profiler::report(
const zakero::Profiler::Data& data
798 (*zakero_profiler.stream)
799 <<
",{\"ph\":\"" << data.phase <<
"\""
800 <<
",\"ts\":" << data.time_stamp
801 <<
",\"pid\":" << data.process_id
802 <<
",\"tid\":" << data.thread_id
803 <<
",\"cat\":\"" << data.category <<
"\""
804 <<
",\"name\":\"" << data.name <<
"\""
806 <<
"{\"file_name\":\"" << data.location.file_name() <<
"\""
807 <<
",\"function_name\":\"" << data.location.function_name() <<
"\""
856 Profiler::Data::Data(
const char phase
857 ,
const std::string& category
858 ,
const std::string& name
859 ,
const std::experimental::source_location& location
864 , time_stamp(TIME_NOW)
865 , thread_id(std::this_thread::get_id())
866 , process_id(ZAKERO_PROFILER_PID)
890 Profiler::Duration::Duration(
const std::string& category
891 ,
const std::string& name
892 ,
const std::experimental::source_location& location
894 : zakero::Profiler::Data(
'B', category, name, location)
895 , was_active(zakero_profiler.is_active)
905 Profiler::Duration::~Duration() noexcept
907 if(was_active || zakero_profiler.is_active)
909 zakero::Profiler::report(*
this);
912 time_stamp = TIME_NOW;
913 zakero::Profiler::report(*
this);
936 Profiler::Instant::Instant(
const std::string& category
937 ,
const std::string& name
938 ,
const std::experimental::source_location& location
940 : zakero::Profiler::Data(
'I', category, name, location)
942 if(zakero_profiler.is_active)
944 zakero::Profiler::report(*
this);
950 #endif // ZAKERO_PROFILER_IMPLEMENTATION
954 #endif // zakero_Profiler_h