ECStatsCollector.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. * Copyright 2005 - 2016 Zarafa and its licensors
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. */
  17. #include <kopano/platform.h>
  18. #include <kopano/lockhelper.hpp>
  19. #include "ECStatsCollector.h"
  20. #include <kopano/stringutil.h>
  21. using namespace std;
  22. namespace KC {
  23. ECStatsCollector::ECStatsCollector() {
  24. // the 'name' parameter may not be longer than 19 characters, since we want to use those in RRDtool
  25. AddStat(SCN_SERVER_STARTTIME, SCDT_TIMESTAMP, "server_start_date", "Time when the server was started");
  26. AddStat(SCN_SERVER_LAST_CACHECLEARED, SCDT_TIMESTAMP, "cache_purge_date", "Time when the cache was cleared");
  27. AddStat(SCN_SERVER_LAST_CONFIGRELOAD, SCDT_TIMESTAMP, "config_reload_date", "Time when the configuration file was reloaded / logrotation (SIGHUP)");
  28. AddStat(SCN_SERVER_CONNECTIONS, SCDT_LONGLONG, "connections", "Number of handled incoming connections");
  29. AddStat(SCN_MAX_SOCKET_NUMBER, SCDT_LONGLONG, "max_socket", "Highest socket number used");
  30. AddStat(SCN_REDIRECT_COUNT, SCDT_LONGLONG, "redirections", "Number of redirected requests");
  31. AddStat(SCN_SEARCHFOLDER_COUNT, SCDT_LONGLONG, "searchfld_loaded", "Total number of searchfolders");
  32. AddStat(SCN_SEARCHFOLDER_THREADS, SCDT_LONGLONG, "searchfld_threads", "Current number of running searchfolder threads");
  33. AddStat(SCN_SEARCHFOLDER_UPDATE_RETRY, SCDT_LONGLONG, "searchupd_retry", "The number of times a search folder update was restarted");
  34. AddStat(SCN_SEARCHFOLDER_UPDATE_FAIL, SCDT_LONGLONG, "searchupd_fail", "The number of failed search folder updates after retrying");
  35. AddStat(SCN_SOAP_REQUESTS, SCDT_LONGLONG, "soap_request", "Number of soap requests handled by server");
  36. AddStat(SCN_RESPONSE_TIME, SCDT_LONGLONG, "response_time", "Response time of soap requests handled in milliseconds (includes time in queue)");
  37. AddStat(SCN_PROCESSING_TIME, SCDT_LONGLONG, "processing_time", "Time taken to process soap requests in milliseconds (wallclock time)");
  38. AddStat(SCN_DATABASE_CONNECTS, SCDT_LONGLONG, "sql_connect", "Number of connections made to SQL server");
  39. AddStat(SCN_DATABASE_SELECTS, SCDT_LONGLONG, "sql_select", "Number of SQL Select commands executed");
  40. AddStat(SCN_DATABASE_INSERTS, SCDT_LONGLONG, "sql_insert", "Number of SQL Insert commands executed");
  41. AddStat(SCN_DATABASE_UPDATES, SCDT_LONGLONG, "sql_update", "Number of SQL Update commands executed");
  42. AddStat(SCN_DATABASE_DELETES, SCDT_LONGLONG, "sql_delete", "Number of SQL Delete commands executed");
  43. AddStat(SCN_DATABASE_FAILED_CONNECTS, SCDT_LONGLONG, "sql_connect_fail", "Number of failed connections made to SQL server");
  44. AddStat(SCN_DATABASE_FAILED_SELECTS, SCDT_LONGLONG, "sql_select_fail", "Number of failed SQL Select commands");
  45. AddStat(SCN_DATABASE_FAILED_INSERTS, SCDT_LONGLONG, "sql_insert_fail", "Number of failed SQL Insert commands");
  46. AddStat(SCN_DATABASE_FAILED_UPDATES, SCDT_LONGLONG, "sql_update_fail", "Number of failed SQL Update commands");
  47. AddStat(SCN_DATABASE_FAILED_DELETES, SCDT_LONGLONG, "sql_delete_fail", "Number of failed SQL Delete commands");
  48. AddStat(SCN_DATABASE_LAST_FAILED, SCDT_TIMESTAMP, "sql_last_fail_time", "Timestamp of last failed SQL command");
  49. AddStat(SCN_DATABASE_MWOPS, SCDT_LONGLONG, "mwops", "MAPI Write Operations");
  50. AddStat(SCN_DATABASE_MROPS, SCDT_LONGLONG, "mrops", "MAPI Read Operations");
  51. AddStat(SCN_DATABASE_DEFERRED_FETCHES, SCDT_LONGLONG, "deferred_fetches", "Number rows retrieved via deferred write table");
  52. AddStat(SCN_DATABASE_MERGES, SCDT_LONGLONG, "deferred_merges", "Number of merges applied to the deferred write table");
  53. AddStat(SCN_DATABASE_MERGED_RECORDS, SCDT_LONGLONG, "deferred_records", "Number records merged in the deferred write table");
  54. AddStat(SCN_DATABASE_ROW_READS, SCDT_LONGLONG, "row_reads", "Number of table rows read in row order");
  55. AddStat(SCN_DATABASE_COUNTER_RESYNCS, SCDT_LONGLONG, "counter_resyncs", "Number of time a counter resync was required");
  56. AddStat(SCN_LOGIN_PASSWORD, SCDT_LONGLONG, "login_password", "Number of logins through password authentication");
  57. AddStat(SCN_LOGIN_SSL, SCDT_LONGLONG, "login_ssl", "Number of logins through SSL certificate authentication");
  58. AddStat(SCN_LOGIN_SSO, SCDT_LONGLONG, "login_sso", "Number of logins through Single Sign-on");
  59. AddStat(SCN_LOGIN_SOCKET, SCDT_LONGLONG, "login_unix", "Number of logins through Unix socket");
  60. AddStat(SCN_LOGIN_DENIED, SCDT_LONGLONG, "login_failed", "Number of failed logins");
  61. AddStat(SCN_SESSIONS_CREATED, SCDT_LONGLONG, "sessions_created", "Number of created sessions");
  62. AddStat(SCN_SESSIONS_DELETED, SCDT_LONGLONG, "sessions_deleted", "Number of deleted sessions");
  63. AddStat(SCN_SESSIONS_TIMEOUT, SCDT_LONGLONG, "sessions_timeout", "Number of timed-out sessions");
  64. AddStat(SCN_SESSIONS_INTERNAL_CREATED, SCDT_LONGLONG, "sess_int_created", "Number of created internal sessions");
  65. AddStat(SCN_SESSIONS_INTERNAL_DELETED, SCDT_LONGLONG, "sess_int_deleted", "Number of deleted internal sessions");
  66. AddStat(SCN_SESSIONGROUPS_CREATED, SCDT_LONGLONG, "sess_grp_created", "Number of created sessiongroups");
  67. AddStat(SCN_SESSIONGROUPS_DELETED, SCDT_LONGLONG, "sess_grp_deleted", "Number of deleted sessiongroups");
  68. AddStat(SCN_LDAP_CONNECTS, SCDT_LONGLONG, "ldap_connect", "Number of connections made to LDAP server");
  69. AddStat(SCN_LDAP_RECONNECTS, SCDT_LONGLONG, "ldap_reconnect", "Number of re-connections made to LDAP server");
  70. AddStat(SCN_LDAP_CONNECT_FAILED, SCDT_LONGLONG, "ldap_connect_fail", "Number of failed connections made to LDAP server");
  71. AddStat(SCN_LDAP_CONNECT_TIME, SCDT_LONGLONG, "ldap_connect_time", "Total duration of connections made to LDAP server");
  72. AddStat(SCN_LDAP_CONNECT_TIME_MAX, SCDT_LONGLONG, "ldap_max_connect", "Longest connection time made to LDAP server");
  73. /* maybe usesless because SCN_LOGIN_* */
  74. AddStat(SCN_LDAP_AUTH_LOGINS, SCDT_LONGLONG, "ldap_auth", "Number of LDAP authentications");
  75. AddStat(SCN_LDAP_AUTH_DENIED, SCDT_LONGLONG, "ldap_auth_fail", "Number of failed authentications");
  76. AddStat(SCN_LDAP_AUTH_TIME, SCDT_LONGLONG, "ldap_auth_time", "Total authentication time");
  77. AddStat(SCN_LDAP_AUTH_TIME_MAX, SCDT_LONGLONG, "ldap_max_auth", "Longest duration of authentication made to LDAP server");
  78. AddStat(SCN_LDAP_AUTH_TIME_AVG, SCDT_LONGLONG, "ldap_avg_auth", "Average duration of authentication made to LDAP server");
  79. AddStat(SCN_LDAP_SEARCH, SCDT_LONGLONG, "ldap_search", "Number of searches made to LDAP server");
  80. AddStat(SCN_LDAP_SEARCH_FAILED, SCDT_LONGLONG, "ldap_search_fail", "Number of failed searches made to LDAP server");
  81. AddStat(SCN_LDAP_SEARCH_TIME, SCDT_LONGLONG, "ldap_search_time", "Total duration of LDAP searches");
  82. AddStat(SCN_LDAP_SEARCH_TIME_MAX, SCDT_LONGLONG, "ldap_max_search", "Longest duration of LDAP search");
  83. AddStat(SCN_INDEXER_SEARCH_ERRORS, SCDT_LONGLONG, "index_search_errors", "Number of failed indexer queries");
  84. AddStat(SCN_INDEXER_SEARCH_MAX, SCDT_LONGLONG, "index_search_max", "Maximum duration of an indexed search query");
  85. AddStat(SCN_INDEXER_SEARCH_AVG, SCDT_LONGLONG, "index_search_avg", "Average duration of an indexed search query");
  86. AddStat(SCN_INDEXED_SEARCHES, SCDT_LONGLONG, "search_indexed", "Number of indexed searches performed");
  87. AddStat(SCN_DATABASE_SEARCHES, SCDT_LONGLONG, "search_database", "Number of database searches performed");
  88. }
  89. void ECStatsCollector::AddStat(SCName index, SCType type, const char *name, const char *description) {
  90. ECStat &newStat = m_StatData[index];
  91. newStat.data.ll = 0; // reset largest data var in union
  92. newStat.avginc = 1;
  93. newStat.type = type;
  94. newStat.name = name;
  95. newStat.description = description;
  96. }
  97. void ECStatsCollector::Increment(SCName name, float inc) {
  98. auto iSD = m_StatData.find(name);
  99. if (iSD == m_StatData.cend())
  100. return;
  101. assert(iSD->second.type == SCDT_FLOAT);
  102. scoped_lock lk(iSD->second.lock);
  103. iSD->second.data.f += inc;
  104. }
  105. void ECStatsCollector::Increment(SCName name, int inc) {
  106. Increment(name, (LONGLONG)inc);
  107. }
  108. void ECStatsCollector::Increment(SCName name, LONGLONG inc) {
  109. auto iSD = m_StatData.find(name);
  110. if (iSD == m_StatData.cend())
  111. return;
  112. assert(iSD->second.type == SCDT_LONGLONG);
  113. scoped_lock lk(iSD->second.lock);
  114. iSD->second.data.ll += inc;
  115. }
  116. void ECStatsCollector::Set(SCName name, float set) {
  117. auto iSD = m_StatData.find(name);
  118. if (iSD == m_StatData.cend())
  119. return;
  120. assert(iSD->second.type == SCDT_FLOAT);
  121. scoped_lock lk(iSD->second.lock);
  122. iSD->second.data.f = set;
  123. }
  124. void ECStatsCollector::Set(SCName name, LONGLONG set) {
  125. auto iSD = m_StatData.find(name);
  126. if (iSD == m_StatData.cend())
  127. return;
  128. assert(iSD->second.type == SCDT_LONGLONG);
  129. scoped_lock lk(iSD->second.lock);
  130. iSD->second.data.ll = set;
  131. }
  132. void ECStatsCollector::SetTime(SCName name, time_t set) {
  133. auto iSD = m_StatData.find(name);
  134. if (iSD == m_StatData.cend())
  135. return;
  136. assert(iSD->second.type == SCDT_TIMESTAMP);
  137. scoped_lock lk(iSD->second.lock);
  138. iSD->second.data.ts = set;
  139. }
  140. void ECStatsCollector::Max(SCName name, LONGLONG max)
  141. {
  142. auto iSD = m_StatData.find(name);
  143. if (iSD == m_StatData.cend())
  144. return;
  145. assert(iSD->second.type == SCDT_LONGLONG);
  146. scoped_lock lk(iSD->second.lock);
  147. if (iSD->second.data.ll < max)
  148. iSD->second.data.ll = max;
  149. }
  150. void ECStatsCollector::Avg(SCName name, float add)
  151. {
  152. auto iSD = m_StatData.find(name);
  153. if (iSD == m_StatData.cend())
  154. return;
  155. assert(iSD->second.type == SCDT_FLOAT);
  156. scoped_lock lk(iSD->second.lock);
  157. iSD->second.data.f = ((add - iSD->second.data.f) / iSD->second.avginc) + iSD->second.data.f;
  158. ++iSD->second.avginc;
  159. if (iSD->second.avginc == 0)
  160. iSD->second.avginc = 1;
  161. }
  162. void ECStatsCollector::Avg(SCName name, LONGLONG add)
  163. {
  164. auto iSD = m_StatData.find(name);
  165. if (iSD == m_StatData.cend())
  166. return;
  167. assert(iSD->second.type == SCDT_LONGLONG);
  168. scoped_lock lk(iSD->second.lock);
  169. iSD->second.data.ll = ((add - iSD->second.data.ll) / iSD->second.avginc) + iSD->second.data.ll;
  170. ++iSD->second.avginc;
  171. if (iSD->second.avginc == 0)
  172. iSD->second.avginc = 1;
  173. }
  174. std::string ECStatsCollector::GetValue(const SCMap::const_iterator::value_type &iSD)
  175. {
  176. std::string rv;
  177. switch (iSD.second.type) {
  178. case SCDT_FLOAT:
  179. rv = stringify_float(iSD.second.data.f);
  180. break;
  181. case SCDT_LONGLONG:
  182. rv = stringify_int64(iSD.second.data.ll);
  183. break;
  184. case SCDT_TIMESTAMP:
  185. if (iSD.second.data.ts > 0) {
  186. char timestamp[128] = { 0 };
  187. struct tm *tm = localtime(&iSD.second.data.ts);
  188. strftime(timestamp, sizeof timestamp, "%a %b %e %T %Y", tm);
  189. rv = timestamp;
  190. }
  191. break;
  192. }
  193. return rv;
  194. }
  195. std::string ECStatsCollector::GetValue(const SCName &name) {
  196. std::string rv;
  197. auto iSD = m_StatData.find(name);
  198. if (iSD != m_StatData.cend())
  199. rv = GetValue(*iSD);
  200. return rv;
  201. }
  202. void ECStatsCollector::ForEachStat(void(callback)(const std::string &, const std::string &, const std::string &, void*), void *obj)
  203. {
  204. for (auto &i : m_StatData) {
  205. scoped_lock lk(i.second.lock);
  206. callback(i.second.name, i.second.description, GetValue(i), obj);
  207. }
  208. }
  209. void ECStatsCollector::ForEachString(void(callback)(const std::string &, const std::string &, const std::string &, void*), void *obj)
  210. {
  211. scoped_lock lk(m_StringsLock);
  212. for (const auto &i : m_StatStrings)
  213. callback(i.first, i.second.description, i.second.value, obj);
  214. }
  215. void ECStatsCollector::Reset() {
  216. for (auto &i : m_StatData) {
  217. // reset largest var in union
  218. scoped_lock lk(i.second.lock);
  219. i.second.data.ll = 0;
  220. }
  221. }
  222. void ECStatsCollector::Reset(SCName name) {
  223. auto iSD = m_StatData.find(name);
  224. if (iSD == m_StatData.cend())
  225. return;
  226. /* reset largest var in union */
  227. scoped_lock lk(iSD->second.lock);
  228. iSD->second.data.ll = 0;
  229. }
  230. } /* namespace */