staticstic.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Tencent is pleased to support the open source community by making wwsearch
  3. * available.
  4. *
  5. * Copyright (C) 2018-present Tencent. All Rights Reserved.
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  8. * use this file except in compliance with the License. You may obtain a copy of
  9. * the License at
  10. *
  11. * https://opensource.org/licenses/Apache-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OF ANY KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations under the License.
  17. */
  18. #pragma once
  19. #include <sys/time.h>
  20. #include <time.h>
  21. #include <memory>
  22. #include <mutex>
  23. #include <string>
  24. #include <tuple>
  25. #include "stat_collector.h"
  26. namespace wwsearch {
  27. class StatEntity {
  28. friend class StatEntity;
  29. public:
  30. explicit StatEntity(int64_t count, uint32_t consume_us) {
  31. count_.Add(count);
  32. consume_us_.Add(consume_us);
  33. }
  34. ~StatEntity() {}
  35. StatEntity(const StatEntity& stat_entity) { *this = stat_entity; }
  36. StatEntity& operator=(const StatEntity& stat_entity) {
  37. this->count_.Add(stat_entity.count_.Get());
  38. this->consume_us_.Merge(stat_entity.consume_us_);
  39. }
  40. StatEntity(StatEntity&& stat_entity) { *this = std::move(stat_entity); }
  41. StatEntity& operator=(StatEntity&& stat_entity) {
  42. this->count_.Add(stat_entity.count_.Get());
  43. this->consume_us_.Merge(stat_entity.consume_us_);
  44. }
  45. void Add(int64_t count, uint64_t consume_us) {
  46. count_.Add(count);
  47. consume_us_.Add(consume_us);
  48. }
  49. uint64_t InvokeCount() { return consume_us_.num(); }
  50. uint64_t Count() { return count_.Get(); }
  51. uint64_t AvgConsumeUs() { return consume_us_.Average(); }
  52. uint64_t MaxConsumeUs() { return consume_us_.max(); }
  53. uint64_t MinConsumeUs() { return consume_us_.min(); }
  54. // 50%, 80%, 90%
  55. std::tuple<uint64_t, uint64_t, uint64_t> ConsumeUs() {
  56. return std::make_tuple<uint64_t, uint64_t, uint64_t>(
  57. consume_us_.Percentile(0.5), consume_us_.Percentile(0.8),
  58. consume_us_.Percentile(0.9));
  59. }
  60. private:
  61. Counter count_;
  62. HistogramImpl consume_us_;
  63. };
  64. /*
  65. template <class T>
  66. class TimeGuard {
  67. friend class TimeGuard;
  68. public:
  69. TimeGuard(T&& body, std::function<void(const std::string& , int64_t ,
  70. uint32_t )>)
  71. : guard_body_(std::forward<T>(body)), start_time_us_(Time::NowMicros()) {
  72. on_exit_scope_ = []() {
  73. };
  74. }
  75. TimeGuard(TimeGuard&& time_guard)
  76. : guard_body_(std::move(time_guard.guard_body_)),
  77. start_time_us_(time_guard.start_time_us_),
  78. on_exist_scope_(std::move(time_guard, on_exit_scope_)) {}
  79. ~TimeGuard() {
  80. }
  81. private:
  82. T guard_body_;
  83. uint64_t start_time_us_;
  84. std::function<void()> on_exit_scope_;
  85. };
  86. */
  87. using ResultEntity = std::map<int, StatEntity>;
  88. using StatNameEntityList = std::map<std::string, ResultEntity>;
  89. using StatNameEntityListPtr = std::shared_ptr<StatNameEntityList>;
  90. static constexpr int kLogMaxSize = 20 * 1024 * 1024; // 20MB
  91. class Staticstic {
  92. public:
  93. static Staticstic* Instance() {
  94. static Staticstic stat("./stat", 10, kLogMaxSize);
  95. return &stat;
  96. }
  97. explicit Staticstic(const std::string& log_file_base, int log_max_num,
  98. int log_max_size)
  99. : stat_name_entity_list_(new StatNameEntityList),
  100. log_file_base_(log_file_base),
  101. log_max_num_(log_max_num),
  102. log_max_size_(log_max_size),
  103. stat_total_time_us_(0),
  104. last_stat_time_us_(Time::NowMicros()),
  105. timeout_level_ms_({10.0, 100.0, 1000.0}),
  106. fd_(NULL) {}
  107. ~Staticstic() {}
  108. void AddStat(const std::string& stat_name, int result,
  109. const struct ::timeval& begin, struct ::timeval* end = NULL);
  110. void AddStat(const std::string& stat_name, int result, int64_t count,
  111. const struct ::timeval& begin, struct ::timeval* end = NULL);
  112. void AddStat(const std::string& stat_name, int result, int64_t count,
  113. uint64_t consume_us);
  114. // TimeGuard AddStatTimeGuard(const std::string& stat_name, int64_t count);
  115. void Report();
  116. private:
  117. void Write(const char* format, ...);
  118. int Reopen();
  119. int SwitchFile();
  120. std::string GetDateString();
  121. std::string BuildHeader();
  122. std::string BuildBody(const StatNameEntityListPtr& stat_name_entity_list);
  123. private:
  124. StatNameEntityListPtr stat_name_entity_list_;
  125. std::mutex mutex_;
  126. std::string log_file_base_;
  127. int log_max_num_;
  128. int log_max_size_;
  129. int stat_total_time_us_;
  130. uint64_t last_stat_time_us_;
  131. std::vector<float> timeout_level_ms_;
  132. FILE* fd_;
  133. };
  134. } // namespace wwsearch