├── .gitignore ├── .gitmodules ├── AUTHORS ├── CMakeLists.txt ├── LICENSE ├── README.md ├── benchmarks ├── CMakeLists.txt ├── command_executor.hpp ├── load.cpp └── run_load.sh ├── debian ├── changelog ├── compat ├── control ├── copyright ├── handystats.install ├── rules └── source │ └── format ├── docs ├── Makefile ├── _static │ └── architecture.svg ├── about.rst ├── architecture.rst ├── conf.py ├── configuration.rst ├── incremental-statistics.rst ├── index.rst ├── metrics.rst └── time-measurement.rst ├── handystats-bf.spec ├── handystats.version ├── include └── handystats │ ├── atomic.hpp │ ├── chrono.h │ ├── chrono.hpp │ ├── common.h │ ├── config │ ├── metrics │ │ ├── counter.hpp │ │ ├── gauge.hpp │ │ └── timer.hpp │ └── statistics.hpp │ ├── core.h │ ├── core.hpp │ ├── json_dump.hpp │ ├── macros.h │ ├── math_utils.hpp │ ├── measuring_points.h │ ├── measuring_points.hpp │ ├── measuring_points │ ├── attribute.h │ ├── attribute.hpp │ ├── attribute_proxy.hpp │ ├── counter.h │ ├── counter.hpp │ ├── counter_proxy.hpp │ ├── gauge.h │ ├── gauge.hpp │ ├── gauge_proxy.hpp │ ├── timer.h │ ├── timer.hpp │ └── timer_proxy.hpp │ ├── metrics.hpp │ ├── metrics │ ├── attribute.hpp │ ├── counter.hpp │ ├── gauge.hpp │ └── timer.hpp │ ├── metrics_dump.hpp │ └── statistics.hpp ├── src ├── chrono.cpp ├── chrono │ ├── system_clock.cpp │ └── tsc_clock.cpp ├── config.cpp ├── config │ ├── core.cpp │ ├── core_impl.hpp │ ├── metrics │ │ ├── counter.cpp │ │ ├── gauge.cpp │ │ └── timer.cpp │ ├── metrics_dump.cpp │ ├── metrics_dump_impl.hpp │ └── statistics.cpp ├── config_impl.hpp ├── core.cpp ├── core_impl.hpp ├── cpuid_impl.hpp ├── events │ ├── attribute.cpp │ ├── attribute_impl.hpp │ ├── counter.cpp │ ├── counter_impl.hpp │ ├── event_message.cpp │ ├── event_message_impl.hpp │ ├── gauge.cpp │ ├── gauge_impl.hpp │ ├── timer.cpp │ └── timer_impl.hpp ├── internal.cpp ├── internal_impl.hpp ├── json │ ├── attribute_json_writer.hpp │ ├── counter_json_writer.hpp │ ├── gauge_json_writer.hpp │ ├── statistics_json_writer.hpp │ ├── timer_json_writer.hpp │ └── timestamp.hpp ├── json_dump.cpp ├── measuring_points │ ├── attribute.cpp │ ├── counter.cpp │ ├── gauge.cpp │ └── timer.cpp ├── message_queue.cpp ├── message_queue_impl.hpp ├── metrics │ ├── attribute.cpp │ ├── counter.cpp │ ├── gauge.cpp │ └── timer.cpp ├── metrics_dump.cpp ├── metrics_dump_impl.hpp └── statistics.cpp └── tests ├── CMakeLists.txt ├── attribute.gtest.cpp ├── attribute_events.gtest.cpp ├── c-binding ├── check.cpp ├── test.c └── test.h ├── configuration.gtest.cpp ├── counter.gtest.cpp ├── counter_events.gtest.cpp ├── event_message_queue.gtest.cpp ├── gauge.gtest.cpp ├── gauge_events.gtest.cpp ├── handy.gtest.cpp ├── handy_timer.gtest.cpp ├── json_dump.gtest.cpp ├── math_utils.gtest.cpp ├── message_queue_helper.hpp ├── metrics_dump.gtest.cpp ├── metrics_dump_helper.hpp ├── proxy.gtest.cpp ├── scoped_counter.gtest.cpp ├── scoped_timer.gtest.cpp ├── statistics.gtest.cpp ├── timer.gtest.cpp └── timer_events.gtest.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | docs/_build/ 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "thirdparty/rapidjson"] 2 | path = thirdparty/rapidjson 3 | url = https://github.com/Tencent/rapidjson 4 | [submodule "thirdparty/googletest"] 5 | path = thirdparty/googletest 6 | url = https://github.com/google/googletest/ 7 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | The following authors have created the source code of "Handystats" 2 | published and distributed by YANDEX LLC as the owner: 3 | 4 | Danil Osherov 5 | Ivan Chelubeev 6 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT (handystats) 2 | CMAKE_MINIMUM_REQUIRED (VERSION 2.8) 3 | 4 | SET (LIB_MAJOR_VERSION "1") 5 | SET (LIB_MINOR_VERSION "11") 6 | SET (LIB_PATCH_VERSION "4") 7 | SET (LIB_SOVERSION "1") 8 | 9 | SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -g -std=c++0x -Wreorder -Wreturn-type -Wunused-variable -pedantic -D_GLIBCXX_USE_NANOSLEEP -D_GLIBCXX_USE_CLOCK_MONOTONIC -D_GLIBCXX_USE_SCHED_YIELD") 10 | 11 | SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -std=c99 -Wreturn-type -Wunused-variable -pedantic -D_GLIBCXX_USE_NANOSLEEP -D_GLIBCXX_USE_CLOCK_MONOTONIC -D_POSIX_C_SOURCE=200809L") 12 | 13 | 14 | GET_PROPERTY (LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS) 15 | 16 | IF (LIB64) 17 | SET (LIBSUFFIX 64) 18 | ELSE () 19 | SET (LIBSUFFIX "") 20 | ENDIF () 21 | 22 | SET (LIBDIR lib${LIBSUFFIX}) 23 | 24 | SET (RAPIDJSON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/rapidjson/include) 25 | 26 | INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/src ${RAPIDJSON_INCLUDE_DIRS}) 27 | 28 | SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBDIR}) 29 | 30 | FILE (GLOB_RECURSE handy_src RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp") 31 | ADD_LIBRARY (${PROJECT_NAME} SHARED ${handy_src}) 32 | 33 | TARGET_LINK_LIBRARIES (${PROJECT_NAME} rt pthread) 34 | 35 | SET_TARGET_PROPERTIES ( 36 | ${PROJECT_NAME} 37 | PROPERTIES 38 | SOVERSION ${LIB_SOVERSION} 39 | VERSION ${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION} 40 | # use linker version script to limit visibility of some symbols 41 | LINK_FLAGS -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/handystats.version 42 | ) 43 | 44 | INSTALL (TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIBDIR}) 45 | INSTALL (DIRECTORY ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/include) 46 | INSTALL (DIRECTORY ${RAPIDJSON_INCLUDE_DIRS}/rapidjson DESTINATION ${CMAKE_INSTALL_PREFIX}/include/handystats) 47 | 48 | ADD_SUBDIRECTORY (benchmarks EXCLUDE_FROM_ALL) 49 | 50 | ENABLE_TESTING () 51 | ADD_SUBDIRECTORY (tests) 52 | 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | Coverity Scan Build Status 4 | 5 | 6 | Handystats is C++ library for collecting **user-defined in-process runtime statistics** with **low overhead**. 7 | 8 | Read our documentation at [http://handystats.readthedocs.org](http://handystats.readthedocs.org). 9 | 10 | Copyright (c) 2013-2015 YANDEX LLC. All rights reserved. 11 | -------------------------------------------------------------------------------- /benchmarks/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) YANDEX LLC. All rights reserved. 3 | # 4 | # This library is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU Lesser General Public 6 | # License as published by the Free Software Foundation; either 7 | # version 3.0 of the License, or (at your option) any later version. 8 | # 9 | # This library is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | # Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public 15 | # License along with this library. 16 | # 17 | 18 | CMAKE_MINIMUM_REQUIRED (VERSION 2.8) 19 | 20 | SET (BENCHMARK_LIBRARIES ${PROJECT_NAME}) 21 | 22 | FIND_PACKAGE (Threads) 23 | IF (Threads_FOUND) 24 | INCLUDE_DIRECTORIES (${Threads_INCLUDE_DIR}) 25 | LIST (APPEND BENCHMARK_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) 26 | ENDIF () 27 | 28 | FIND_PACKAGE (Boost COMPONENTS program_options) 29 | IF (Boost_PROGRAM_OPTIONS_FOUND) 30 | INCLUDE_DIRECTORIES (${Boost_INCLUDE_DIR}) 31 | LIST (APPEND BENCHMARK_LIBRARIES ${Boost_PROGRAM_OPTIONS_LIBRARY}) 32 | ENDIF () 33 | 34 | SET (BENCHMARK_LINK_FLAGS "-Wl,-rpath,${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_CURRENT_BINARY_DIR}/../${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") 35 | SET (BENCHMARK_PROPERTIES PROPERTIES LINK_FLAGS "${BENCHMARK_LINK_FLAGS}" LINKER_LANGUAGE CXX) 36 | 37 | ADD_CUSTOM_TARGET(benchmarks) 38 | 39 | ADD_EXECUTABLE (load EXCLUDE_FROM_ALL ${CMAKE_CURRENT_SOURCE_DIR}/load.cpp) 40 | SET_TARGET_PROPERTIES (load ${BENCHMARK_PROPERTIES}) 41 | TARGET_LINK_LIBRARIES (load ${BENCHMARK_LIBRARIES}) 42 | ADD_DEPENDENCIES (benchmarks load) 43 | 44 | FILE (COPY run_load.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) 45 | -------------------------------------------------------------------------------- /benchmarks/command_executor.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_BENCHMARKS_COMMAND_EXECUTOR_HPP_ 19 | #define HANDYSTATS_BENCHMARKS_COMMAND_EXECUTOR_HPP_ 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace handystats { namespace benchmarks { 28 | 29 | struct command_executor { 30 | typedef std::function command_type; 31 | 32 | static 33 | chrono::duration 34 | run_command( 35 | command_type command 36 | ) 37 | { 38 | auto start_time = chrono::tsc_clock::now(); 39 | command(); 40 | auto end_time = chrono::tsc_clock::now(); 41 | 42 | return end_time - start_time; 43 | } 44 | 45 | static 46 | chrono::duration 47 | run_command_for( 48 | command_type command, 49 | chrono::duration time_limit 50 | ) 51 | { 52 | auto start_time = chrono::tsc_clock::now(); 53 | auto call_time = run_command(command); 54 | 55 | while (call_time < time_limit) { 56 | if (time_limit - call_time > chrono::duration(100, chrono::time_unit::USEC)) { 57 | std::this_thread::sleep_for(std::chrono::microseconds(10)); 58 | } 59 | else { 60 | std::this_thread::yield(); 61 | } 62 | call_time = chrono::tsc_clock::now() - start_time; 63 | } 64 | 65 | return call_time; 66 | } 67 | 68 | static 69 | chrono::duration 70 | run_for( 71 | command_type command, 72 | chrono::duration command_time_limit, 73 | chrono::duration total_time_limit 74 | ) 75 | { 76 | chrono::duration total_time(0, chrono::time_unit::TICK); 77 | 78 | while (total_time < total_time_limit) { 79 | total_time += run_command_for(command, command_time_limit); 80 | } 81 | 82 | return total_time; 83 | } 84 | 85 | }; // struct command_executor 86 | 87 | }} // namespace handystats::benchmarks 88 | 89 | #endif // HANDYSTATS_BENCHMARKS_COMMAND_EXECUTOR_HPP_ 90 | -------------------------------------------------------------------------------- /benchmarks/run_load.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | handystats_config="{ 4 | \"enabled\": true, 5 | \"defaults\": { 6 | \"moving-interval\": 1000, 7 | \"histogram-bins\": 20, 8 | \"tags\": [] 9 | }, 10 | \"load_test.counter.*\": { 11 | \"tags\": [\"value\", \"moving-avg\"] 12 | }, 13 | \"load_test.gauge.*\": { 14 | \"tags\": [\"value\", \"moving-avg\"] 15 | }, 16 | \"load_test.timer.*\": { 17 | \"tags\": [\"quantile\", \"moving-avg\"] 18 | } 19 | }" 20 | 21 | # Number of working threads (excluding handystats' thread and stats printing thread) 22 | threads=2 23 | 24 | # Number of metrics with specific type (sum must be > 0) 25 | gauges=5 26 | counters=5 27 | timers=5 28 | 29 | # Stats printing interval (ms) 30 | output_interval=1000 31 | 32 | # Array of pairs (rate, time_limit), time_limit in seconds 33 | steps=( 34 | 1000 10 35 | 5000 10 36 | 10000 10 37 | 20000 10 38 | 50000 10 39 | 100000 10 40 | ) 41 | 42 | exe_path="`pwd`/load" 43 | 44 | if [ $# -ge 1 ]; 45 | then 46 | exe_path=$1; 47 | fi 48 | 49 | $exe_path \ 50 | --handystats-config "$handystats_config" \ 51 | --threads $threads \ 52 | --gauges $gauges \ 53 | --counters $counters \ 54 | --timers $timers \ 55 | --step ${steps[*]} \ 56 | --output-interval $output_interval \ 57 | 58 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: handystats 2 | Priority: optional 3 | Section: libs 4 | Maintainer: Danil Osherov 5 | Build-Depends: debhelper (>= 7), 6 | cmake, 7 | libboost-dev, 8 | Standards-Version: 3.9.5 9 | Homepage: https://github.com/yandex/handystats 10 | Vcs-git: git://github.com/yandex/handystats.git 11 | Vcs-Browser: https://github.com/yandex/handystats 12 | 13 | Package: handystats 14 | Architecture: any 15 | Section: libdevel 16 | Depends: ${shlibs:Depends}, ${misc:Depends} 17 | Description: C++ library for user-defined in-process runtime statistics 18 | Handystats is C++ library for collecting user-defined 19 | in-process runtime statistics with low overhead that allows 20 | users to monitor their applications in a production 21 | environment. 22 | 23 | Package: handystats-dbg 24 | Architecture: any 25 | Priority: extra 26 | Section: debug 27 | Depends: ${misc:Depends}, handystats (= ${binary:Version}) 28 | Description: C++ library for user-defined in-process runtime statistics debug files 29 | Handystats is C++ library for collecting user-defined 30 | in-process runtime statistics with low overhead that allows 31 | users to monitor their applications in a production 32 | environment. 33 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | 3 | Files: * 4 | Copyright: 2013-2015 YANDEX LLC 5 | License: LGPL-3+ 6 | Source: /usr/share/common-licenses/LGPL-3 7 | -------------------------------------------------------------------------------- /debian/handystats.install: -------------------------------------------------------------------------------- 1 | usr/lib 2 | usr/include 3 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | %: 4 | dh $@ 5 | 6 | override_dh_auto_configure: 7 | cmake -DCMAKE_VERBOSE_MAKEFILE=1 -DCMAKE_INSTALL_PREFIX:PATH=/usr 8 | 9 | override_dh_auto_build: 10 | make -j4 11 | 12 | override_dh_auto_test: 13 | make check 14 | 15 | override_dh_strip: 16 | dh_strip --dbg-package=handystats-dbg 17 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /docs/architecture.rst: -------------------------------------------------------------------------------- 1 | .. _architecture: 2 | 3 | Architecture 4 | ============ 5 | 6 | Handystats library consists of the following components: 7 | 8 | - metrics 9 | - measuring points 10 | - event message queue 11 | - processing core 12 | - metrics and JSON dumps 13 | 14 | Here is an example of relation between user's application and handystats library: 15 | 16 | .. image:: _static/architecture.svg 17 | :width: 80 % 18 | :align: center 19 | 20 | 21 | Metrics 22 | ------- 23 | 24 | **Metrics** is the base of handystats library statistics. 25 | 26 | You're able to use metrics objects locally in your application, 27 | but our main and preferable way of handling metrics is via measuring points. 28 | 29 | See Metrics documentation for more details. 30 | 31 | Measuring Points 32 | ---------------- 33 | 34 | **Measuring points** are the way to handle metrics resided inside handystats library core by passing event messages to them. 35 | 36 | Examples of measuring points are: 37 | 38 | .. code-block:: cpp 39 | 40 | HANDY_TIMER_START("timer"); 41 | 42 | HANDY_COUNTER_INCREMENT("counter", 1); 43 | 44 | See Measuring Points documentation for more details. 45 | 46 | Event Message Queue 47 | ------------------------------ 48 | 49 | **Events** describe actions that should be taken on metrics stored inside handystats library core. 50 | Such events are passed to the handystats library core by measuring points, which form certain events and push them into event message queue. 51 | 52 | **Event message queue** is one-way communication channel between user's application and handystats library core. 53 | User's application with use of measuring points publishes event messages to the queue and handystats library core processes them. 54 | 55 | Since there's single message queue it's prone to become system's bottleneck especially in multithreaded environment. 56 | To solve this problem we've designed this part of handystats library *lock-free*. 57 | 58 | Processing Core 59 | --------------- 60 | 61 | **Handystats library core** is the place where *hidden from user* work is done. 62 | Here separate processing thread receives event messages from the event message queue and appropriately updates internal metrics. 63 | 64 | At a time it updates *metics* and *json dumps* of internal metrics state which can be accessed immediately. 65 | 66 | Metrics And JSON Dumps 67 | ---------------------- 68 | 69 | **Metrics** and **JSON dumps** are representation of internal metrics snap (which we call *dump*) in different formats. 70 | 71 | **Metrics dump** is dump in object format (:code:`std::map`) which can be easily used by user's application in runtime. 72 | 73 | **JSON dump** is dump in JSON text representation which can be printed or sended further. 74 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. Handystats documentation master file, created by 2 | sphinx-quickstart on Tue Jun 17 16:37:13 2014. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to Handystats' documentation! 7 | ====================================== 8 | 9 | Handystats is C++ library for collecting **user-defined in-process runtime statistics**. 10 | 11 | Handystats allows users to monitor their **multithreaded applications** in a **production environment** with **low overhead**. 12 | 13 | .. caution:: 14 | Handystats library is in **"beta" phase**. 15 | Everything may be changed! 16 | 17 | Contents: 18 | 19 | .. toctree:: 20 | :maxdepth: 2 21 | 22 | about 23 | architecture 24 | incremental-statistics 25 | metrics 26 | configuration 27 | time-measurement 28 | 29 | -------------------------------------------------------------------------------- /handystats-bf.spec: -------------------------------------------------------------------------------- 1 | Name: handystats 2 | Version: 1.11.6 3 | Release: 1%{?dist} 4 | Summary: C++ library for collecting user-defined in-process runtime statistics with low overhead. 5 | Group: System Environment/Libraries 6 | License: LGPLv3+ 7 | URL: https://github.com/shindo/handystats 8 | Source0: %{name}-%{version}.tar.bz2 9 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) 10 | 11 | %if %{defined rhel} && 0%{?rhel} < 7 12 | BuildRequires: cmake28 13 | %else 14 | BuildRequires: cmake 15 | %endif 16 | 17 | BuildRequires: boost-devel 18 | BuildRequires: gtest-devel 19 | 20 | %description 21 | C++ library for collecting user-defined in-process runtime statistics with low overhead. 22 | 23 | %prep 24 | %setup -q 25 | 26 | %build 27 | mkdir -p %{_target_platform} 28 | pushd %{_target_platform} 29 | 30 | %if %{defined rhel} && 0%{?rhel} < 7 31 | %{cmake28} .. 32 | %else 33 | %{cmake} .. 34 | %endif 35 | 36 | popd 37 | 38 | make %{?_smp_mflags} -C %{_target_platform} 39 | 40 | %check 41 | make check -C %{_target_platform} 42 | 43 | %install 44 | rm -rf %{buildroot} 45 | make install DESTDIR=%{buildroot} -C %{_target_platform} 46 | 47 | %post -p /sbin/ldconfig 48 | %postun -p /sbin/ldconfig 49 | 50 | %clean 51 | rm -rf %{buildroot} 52 | 53 | %files 54 | %defattr(-,root,root,-) 55 | %{_includedir}/handystats/* 56 | %{_libdir}/*handystats*.so* 57 | 58 | #%changelog 59 | -------------------------------------------------------------------------------- /handystats.version: -------------------------------------------------------------------------------- 1 | { 2 | global: 3 | *; 4 | local: 5 | extern "C++" { 6 | *rapidjson::*; 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /include/handystats/atomic.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_ATOMIC_HPP_ 19 | #define HANDYSTATS_ATOMIC_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #endif // HANDYSTATS_ATOMIC_HPP_ 26 | -------------------------------------------------------------------------------- /include/handystats/chrono.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_CHRONO_H_ 19 | #define HANDYSTATS_CHRONO_H_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | HANDYSTATS_EXTERN_C 26 | int64_t handystats_now(void); 27 | 28 | HANDYSTATS_EXTERN_C 29 | double handystats_difftime(int64_t end, int64_t start); 30 | 31 | #endif // HANDYSTATS_CHRONO_H_ 32 | -------------------------------------------------------------------------------- /include/handystats/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_COMMON_H_ 19 | #define HANDYSTATS_COMMON_H_ 20 | 21 | #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 22 | 23 | /* extern */ 24 | #ifdef __cplusplus 25 | #define HANDYSTATS_EXTERN_C extern "C" 26 | #else 27 | #define HANDYSTATS_EXTERN_C extern 28 | #endif 29 | 30 | /* noexcept */ 31 | #ifdef __cplusplus 32 | #define HANDYSTATS_NOEXCEPT noexcept 33 | #endif 34 | 35 | #endif // HANDYSTATS_COMMON_H_ 36 | -------------------------------------------------------------------------------- /include/handystats/config/metrics/counter.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_CONFIG_METRICS_COUNTER_HPP_ 19 | #define HANDYSTATS_CONFIG_METRICS_COUNTER_HPP_ 20 | 21 | #include 22 | 23 | namespace handystats { namespace config { namespace metrics { 24 | 25 | struct counter { 26 | statistics values; 27 | 28 | counter(); 29 | }; 30 | 31 | }}} // namespace handystats::config::metrics 32 | 33 | #endif // HANDYSTATS_CONFIG_METRICS_COUNTER_HPP_ 34 | -------------------------------------------------------------------------------- /include/handystats/config/metrics/gauge.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_CONFIG_METRICS_GAUGE_HPP_ 19 | #define HANDYSTATS_CONFIG_METRICS_GAUGE_HPP_ 20 | 21 | #include 22 | 23 | namespace handystats { namespace config { namespace metrics { 24 | 25 | struct gauge { 26 | statistics values; 27 | 28 | gauge(); 29 | }; 30 | 31 | }}} // namespace handystats::config::metrics 32 | 33 | #endif // HANDYSTATS_CONFIG_METRICS_GAUGE_HPP_ 34 | -------------------------------------------------------------------------------- /include/handystats/config/metrics/timer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_CONFIG_METRICS_TIMER_HPP_ 19 | #define HANDYSTATS_CONFIG_METRICS_TIMER_HPP_ 20 | 21 | #include 22 | #include 23 | 24 | namespace handystats { namespace config { namespace metrics { 25 | 26 | struct timer { 27 | chrono::duration idle_timeout; 28 | statistics values; 29 | 30 | timer(); 31 | }; 32 | 33 | }}} // namespace handystats::config::metrics 34 | 35 | #endif // HANDYSTATS_CONFIG_METRICS_TIMER_HPP_ 36 | -------------------------------------------------------------------------------- /include/handystats/config/statistics.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_CONFIG_INCREMENTAL_STATISTICS_HPP_ 19 | #define HANDYSTATS_CONFIG_INCREMENTAL_STATISTICS_HPP_ 20 | 21 | #include 22 | 23 | namespace handystats { namespace config { 24 | 25 | struct statistics { 26 | chrono::duration moving_interval; 27 | size_t histogram_bins; 28 | int tags; 29 | chrono::time_unit rate_unit; 30 | 31 | statistics(); 32 | }; 33 | 34 | }} // namespace handystats::config 35 | 36 | #endif // HANDYSTATS_CONFIG_INCREMENTAL_STATISTICS_HPP_ 37 | -------------------------------------------------------------------------------- /include/handystats/core.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_CORE_H_ 19 | #define HANDYSTATS_CORE_H_ 20 | 21 | #include 22 | 23 | /* 24 | * Old configuration format 25 | * { 26 | * "core": { 27 | * "enable": 28 | * }, 29 | * "statistics": { 30 | * "moving-interval": , 31 | * "histogram-bins": , 32 | * "tags": ["", "", ...], 33 | * "rate-unit": <"ns" | "us" | "ms" | "s" | "m" | "h"> 34 | * }, 35 | * "metrics": { 36 | * "gauge": { 37 | * 38 | * }, 39 | * "counter": { 40 | * 41 | * }, 42 | * "timer": { 43 | * "idle-timeout": , 44 | * 45 | * } 46 | * }, 47 | * "metrics-dump": { 48 | * "interval": 49 | * }, 50 | * "": { 51 | * 52 | * } 53 | * } 54 | */ 55 | 56 | /* 57 | * New configuration format 58 | * { 59 | * "enable": , 60 | * "dump-interval": , 61 | * "defaults": { 62 | * "moving-interval": , 63 | * "histogram-bins": , 64 | * "tags": ["", "", ...], 65 | * "rate-unit": <"ns" | "us" | "ms" | "s" | "m" | "h"> 66 | * }, 67 | * "gauge": { 68 | * 69 | * }, 70 | * "counter": { 71 | * 72 | * }, 73 | * "timer": { 74 | * "idle-timeout": , 75 | * 76 | * }, 77 | * "": { 78 | * 79 | * } 80 | * } 81 | */ 82 | 83 | HANDYSTATS_EXTERN_C 84 | void handystats_initialize(); 85 | 86 | HANDYSTATS_EXTERN_C 87 | void handystats_finalize(); 88 | 89 | HANDYSTATS_EXTERN_C 90 | int handystats_config_file(const char* filename); 91 | 92 | HANDYSTATS_EXTERN_C 93 | int handystats_config_json(const char* config); 94 | 95 | 96 | #ifndef __cplusplus 97 | #ifndef HANDYSTATS_DISABLE 98 | 99 | #define HANDY_INIT(...) handystats_initialize(__VA_ARGS__) 100 | 101 | #define HANDY_FINALIZE(...) handystats_finalize(__VA_ARGS__) 102 | 103 | #define HANDY_CONFIG_FILE(...) handystats_config_file(__VA_ARGS__) 104 | 105 | #define HANDY_CONFIG_JSON(...) handystats_config_json(__VA_ARGS__) 106 | 107 | #else 108 | 109 | #define HANDY_INIT(...) 110 | 111 | #define HANDY_FINALIZE(...) 112 | 113 | #define HANDY_CONFIG_FILE(...) 114 | 115 | #define HANDY_CONFIG_JSON(...) 116 | 117 | #endif 118 | #endif 119 | 120 | #endif // HANDYSTATS_CORE_H_ 121 | -------------------------------------------------------------------------------- /include/handystats/core.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_CORE_HPP_ 19 | #define HANDYSTATS_CORE_HPP_ 20 | 21 | /* 22 | * Old configuration format 23 | * { 24 | * "core": { 25 | * "enable": 26 | * }, 27 | * "statistics": { 28 | * "moving-interval": , 29 | * "histogram-bins": , 30 | * "tags": ["", "", ...], 31 | * "rate-unit": <"ns" | "us" | "ms" | "s" | "m" | "h"> 32 | * }, 33 | * "metrics": { 34 | * "gauge": { 35 | * 36 | * }, 37 | * "counter": { 38 | * 39 | * }, 40 | * "timer": { 41 | * "idle-timeout": , 42 | * 43 | * } 44 | * }, 45 | * "metrics-dump": { 46 | * "interval": 47 | * }, 48 | * "": { 49 | * 50 | * } 51 | * } 52 | */ 53 | 54 | /* 55 | * New configuration format 56 | * { 57 | * "enable": , 58 | * "dump-interval": , 59 | * "defaults": { 60 | * "moving-interval": , 61 | * "histogram-bins": , 62 | * "tags": ["", "", ...], 63 | * "rate-unit": <"ns" | "us" | "ms" | "s" | "m" | "h"> 64 | * }, 65 | * "gauge": { 66 | * 67 | * }, 68 | * "counter": { 69 | * 70 | * }, 71 | * "timer": { 72 | * "idle-timeout": , 73 | * 74 | * }, 75 | * "": { 76 | * 77 | * } 78 | * } 79 | */ 80 | 81 | namespace handystats { 82 | 83 | void initialize(); 84 | 85 | void finalize(); 86 | 87 | bool config_file(const char* filename); 88 | bool config_json(const char* config); 89 | 90 | } // namespace handystats 91 | 92 | 93 | #ifndef HANDYSTATS_DISABLE 94 | 95 | #define HANDY_INIT(...) handystats::initialize(__VA_ARGS__) 96 | 97 | #define HANDY_FINALIZE(...) handystats::finalize(__VA_ARGS__) 98 | 99 | #define HANDY_CONFIG_FILE(...) handystats::config_file(__VA_ARGS__) 100 | 101 | #define HANDY_CONFIG_JSON(...) handystats::config_json(__VA_ARGS__) 102 | 103 | #else 104 | 105 | #define HANDY_INIT(...) 106 | 107 | #define HANDY_FINALIZE(...) 108 | 109 | #define HANDY_CONFIG_FILE(...) 110 | 111 | #define HANDY_CONFIG_JSON(...) 112 | 113 | #endif 114 | 115 | #endif // HANDYSTATS_CORE_HPP_ 116 | -------------------------------------------------------------------------------- /include/handystats/json_dump.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_JSON_DUMP_HPP_ 19 | #define HANDYSTATS_JSON_DUMP_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | namespace handystats { namespace json { 26 | 27 | std::string to_string(const std::map&); 28 | 29 | }} // namespace handystats::json 30 | 31 | std::string HANDY_JSON_DUMP(); 32 | 33 | #endif // HANDYSTATS_JSON_DUMP_HPP_ 34 | -------------------------------------------------------------------------------- /include/handystats/math_utils.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_MATH_UTILS_IMPL_HPP_ 19 | #define HANDYSTATS_MATH_UTILS_IMPL_HPP_ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | namespace handystats { 27 | 28 | class math_utils 29 | { 30 | public: 31 | template 32 | static int cmp(const Value& a, const Value& b, const Value& epsilon = std::numeric_limits::epsilon() * 4) 33 | { 34 | if (a + epsilon < b) { 35 | return -1; 36 | } 37 | if (a - epsilon > b) { 38 | return 1; 39 | } 40 | return 0; 41 | } 42 | 43 | template 44 | static long double sqrt(const Value& a) 45 | { 46 | if (cmp(a, static_cast(0)) < 0) { 47 | throw std::logic_error("sqrt of negative number"); 48 | } 49 | return std::sqrt(static_cast(a)); 50 | } 51 | 52 | // a x^2 + b x + c = 0 53 | static std::vector 54 | solve_quadratic(const long double& a, const long double& b, const long double& c) 55 | { 56 | // b x + c = 0 57 | if (cmp(a, 0.0) == 0) { 58 | if (cmp(b, 0.0) == 0) { 59 | return {}; 60 | } 61 | else { 62 | return {- c / b}; 63 | } 64 | } 65 | else { 66 | double d = b * b - 4 * a * c; 67 | if (cmp(d, 0.0) < 0) { 68 | return {}; 69 | } 70 | else if (cmp(d, 0.0) == 0) { 71 | return { - b / 2.0 / a }; 72 | } 73 | else { 74 | d = sqrt(d); 75 | return {(-d - b) / 2.0 / a, (d - b) / 2.0 / a}; 76 | } 77 | } 78 | 79 | return {}; 80 | } 81 | 82 | static long double 83 | weighted_average( 84 | const long double& value1, const long double& weight1, 85 | const long double& value2, const long double& weight2 86 | ) 87 | { 88 | const long double& total_weight = weight1 + weight2; 89 | if (cmp(total_weight, 0) == 0) { 90 | throw std::logic_error("weighted_average: zero total weight"); 91 | } 92 | 93 | const long double& weighted_sum = value1 * weight1 + value2 * weight2; 94 | 95 | return weighted_sum / total_weight; 96 | } 97 | 98 | }; // class math_utils 99 | 100 | } // namespace handystats 101 | 102 | #endif // HANDYSTATS_MATH_UTILS_IMPL_HPP_ 103 | -------------------------------------------------------------------------------- /include/handystats/measuring_points.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_MEASURING_POINTS_H_ 19 | #define HANDYSTATS_MEASURING_POINTS_H_ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #endif // HANDYSTATS_MEASURING_POINTS_H_ 27 | -------------------------------------------------------------------------------- /include/handystats/measuring_points.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_MEASURING_POINTS_HPP_ 19 | #define HANDYSTATS_MEASURING_POINTS_HPP_ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #endif // HANDYSTATS_MEASURING_POINTS_HPP_ 32 | -------------------------------------------------------------------------------- /include/handystats/measuring_points/attribute.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_ATTRIBUTE_MEASURING_POINTS_H_ 19 | #define HANDYSTATS_ATTRIBUTE_MEASURING_POINTS_H_ 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | HANDYSTATS_EXTERN_C 27 | void handystats_attribute_set_bool( 28 | const char* attribute_name, 29 | const char b 30 | ); 31 | 32 | HANDYSTATS_EXTERN_C 33 | void handystats_attribute_set_int( 34 | const char* attribute_name, 35 | const int i 36 | ); 37 | 38 | HANDYSTATS_EXTERN_C 39 | void handystats_attribute_set_uint( 40 | const char* attribute_name, 41 | const unsigned u 42 | ); 43 | 44 | HANDYSTATS_EXTERN_C 45 | void handystats_attribute_set_int64( 46 | const char* attribute_name, 47 | const int64_t i64 48 | ); 49 | 50 | HANDYSTATS_EXTERN_C 51 | void handystats_attribute_set_uint64( 52 | const char* attribute_name, 53 | const uint64_t u64 54 | ); 55 | 56 | HANDYSTATS_EXTERN_C 57 | void handystats_attribute_set_double( 58 | const char* attribute_name, 59 | const double d 60 | ); 61 | 62 | HANDYSTATS_EXTERN_C 63 | void handystats_attribute_set_string( 64 | const char* attribute_name, 65 | const char* s 66 | ); 67 | 68 | 69 | #ifndef __cplusplus 70 | #ifndef HANDYSTATS_DISABLE 71 | 72 | #define HANDY_ATTRIBUTE_SET_BOOL(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_attribute_set_bool, __VA_ARGS__) 73 | 74 | #define HANDY_ATTRIBUTE_SET_INT(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_attribute_set_int, __VA_ARGS__) 75 | 76 | #define HANDY_ATTRIBUTE_SET_UINT(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_attribute_set_uint, __VA_ARGS__) 77 | 78 | #define HANDY_ATTRIBUTE_SET_INT64(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_attribute_set_int64, __VA_ARGS__) 79 | 80 | #define HANDY_ATTRIBUTE_SET_UINT64(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_attribute_set_uint64, __VA_ARGS__) 81 | 82 | #define HANDY_ATTRIBUTE_SET_DOUBLE(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_attribute_set_double, __VA_ARGS__) 83 | 84 | #define HANDY_ATTRIBUTE_SET_STRING(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_attribute_set_string, __VA_ARGS__) 85 | 86 | #else 87 | 88 | #define HANDY_ATTRIBUTE_SET_BOOL(...) 89 | 90 | #define HANDY_ATTRIBUTE_SET_INT(...) 91 | 92 | #define HANDY_ATTRIBUTE_SET_UINT(...) 93 | 94 | #define HANDY_ATTRIBUTE_SET_INT64(...) 95 | 96 | #define HANDY_ATTRIBUTE_SET_UINT64(...) 97 | 98 | #define HANDY_ATTRIBUTE_SET_DOUBLE(...) 99 | 100 | #define HANDY_ATTRIBUTE_SET_STRING(...) 101 | 102 | #endif 103 | 104 | #endif 105 | 106 | #endif // HANDYSTATS_ATTRIBUTE_MEASURING_POINTS_H_ 107 | -------------------------------------------------------------------------------- /include/handystats/measuring_points/attribute.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_ATTRIBUTE_MEASURING_POINTS_HPP_ 19 | #define HANDYSTATS_ATTRIBUTE_MEASURING_POINTS_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | 29 | namespace handystats { namespace measuring_points { 30 | 31 | template 32 | void attribute_set( 33 | std::string&& attribute_name, 34 | const ValueType& value, 35 | const handystats::metrics::attribute::time_point& timestamp = handystats::metrics::attribute::clock::now() 36 | ); 37 | 38 | template <> 39 | void attribute_set( 40 | std::string&& attribute_name, 41 | const handystats::metrics::attribute::value_type& value, 42 | const handystats::metrics::attribute::time_point& timestamp 43 | ); 44 | 45 | template <> 46 | void attribute_set( 47 | std::string&& attribute_name, 48 | const bool& b, 49 | const handystats::metrics::attribute::time_point& timestamp 50 | ); 51 | 52 | template <> 53 | void attribute_set( 54 | std::string&& attribute_name, 55 | const int& i, 56 | const handystats::metrics::attribute::time_point& timestamp 57 | ); 58 | 59 | template <> 60 | void attribute_set( 61 | std::string&& attribute_name, 62 | const unsigned& u, 63 | const handystats::metrics::attribute::time_point& timestamp 64 | ); 65 | 66 | template <> 67 | void attribute_set( 68 | std::string&& attribute_name, 69 | const int64_t& i64, 70 | const handystats::metrics::attribute::time_point& timestamp 71 | ); 72 | 73 | template <> 74 | void attribute_set( 75 | std::string&& attribute_name, 76 | const uint64_t& u64, 77 | const handystats::metrics::attribute::time_point& timestamp 78 | ); 79 | 80 | template <> 81 | void attribute_set( 82 | std::string&& attribute_name, 83 | const double& d, 84 | const handystats::metrics::attribute::time_point& timestamp 85 | ); 86 | 87 | template <> 88 | void attribute_set( 89 | std::string&& attribute_name, 90 | const std::string& s, 91 | const handystats::metrics::attribute::time_point& timestamp 92 | ); 93 | 94 | }} // namespace handystats::measuring_points 95 | 96 | 97 | #ifndef HANDYSTATS_DISABLE 98 | 99 | #define HANDY_ATTRIBUTE_SET(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats::measuring_points::attribute_set, __VA_ARGS__) 100 | 101 | #define HANDY_ATTRIBUTE_SET_BOOL(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats::measuring_points::attribute_set, __VA_ARGS__) 102 | 103 | #define HANDY_ATTRIBUTE_SET_INT(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats::measuring_points::attribute_set, __VA_ARGS__) 104 | 105 | #define HANDY_ATTRIBUTE_SET_UINT(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats::measuring_points::attribute_set, __VA_ARGS__) 106 | 107 | #define HANDY_ATTRIBUTE_SET_INT64(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats::measuring_points::attribute_set, __VA_ARGS__) 108 | 109 | #define HANDY_ATTRIBUTE_SET_UINT64(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats::measuring_points::attribute_set, __VA_ARGS__) 110 | 111 | #define HANDY_ATTRIBUTE_SET_DOUBLE(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats::measuring_points::attribute_set, __VA_ARGS__) 112 | 113 | #define HANDY_ATTRIBUTE_SET_STRING(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats::measuring_points::attribute_set, __VA_ARGS__) 114 | 115 | #else 116 | 117 | #define HANDY_ATTRIBUTE_SET(...) 118 | 119 | #define HANDY_ATTRIBUTE_SET_BOOL(...) 120 | 121 | #define HANDY_ATTRIBUTE_SET_INT(...) 122 | 123 | #define HANDY_ATTRIBUTE_SET_UINT(...) 124 | 125 | #define HANDY_ATTRIBUTE_SET_INT64(...) 126 | 127 | #define HANDY_ATTRIBUTE_SET_UINT64(...) 128 | 129 | #define HANDY_ATTRIBUTE_SET_DOUBLE(...) 130 | 131 | #define HANDY_ATTRIBUTE_SET_STRING(...) 132 | 133 | #endif 134 | 135 | #endif // HANDYSTATS_ATTRIBUTE_MEASURING_POINTS_HPP_ 136 | -------------------------------------------------------------------------------- /include/handystats/measuring_points/attribute_proxy.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_MEASURING_POINTS_ATTRIBUTE_PROXY_HPP_ 19 | #define HANDYSTATS_MEASURING_POINTS_ATTRIBUTE_PROXY_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | 27 | #include 28 | 29 | namespace handystats { namespace measuring_points { 30 | 31 | class attribute_proxy { 32 | public: 33 | attribute_proxy(const std::string& name) 34 | : name(name) 35 | {} 36 | 37 | attribute_proxy(const char* name) 38 | : name(name) 39 | {} 40 | 41 | void set( 42 | const metrics::attribute::value_type& value, 43 | const metrics::attribute::time_point& timestamp = metrics::attribute::clock::now() 44 | ) 45 | { 46 | HANDY_ATTRIBUTE_SET(name.substr(), value, timestamp); 47 | } 48 | 49 | void set( 50 | const bool& b, 51 | const metrics::attribute::time_point& timestamp = metrics::attribute::clock::now() 52 | ) 53 | { 54 | HANDY_ATTRIBUTE_SET_BOOL(name.substr(), b, timestamp); 55 | } 56 | 57 | void set( 58 | const int& i, 59 | const metrics::attribute::time_point& timestamp = metrics::attribute::clock::now() 60 | ) 61 | { 62 | HANDY_ATTRIBUTE_SET_INT(name.substr(), i, timestamp); 63 | } 64 | 65 | void set( 66 | const unsigned& u, 67 | const metrics::attribute::time_point& timestamp = metrics::attribute::clock::now() 68 | ) 69 | { 70 | HANDY_ATTRIBUTE_SET_UINT(name.substr(), u, timestamp); 71 | } 72 | 73 | void set( 74 | const int64_t& i64, 75 | const metrics::attribute::time_point& timestamp = metrics::attribute::clock::now() 76 | ) 77 | { 78 | HANDY_ATTRIBUTE_SET_INT64(name.substr(), i64, timestamp); 79 | } 80 | 81 | void set( 82 | const uint64_t& u64, 83 | const metrics::attribute::time_point& timestamp = metrics::attribute::clock::now() 84 | ) 85 | { 86 | HANDY_ATTRIBUTE_SET_UINT64(name.substr(), u64, timestamp); 87 | } 88 | 89 | void set( 90 | const double& d, 91 | const metrics::attribute::time_point& timestamp = metrics::attribute::clock::now() 92 | ) 93 | { 94 | HANDY_ATTRIBUTE_SET_DOUBLE(name.substr(), d, timestamp); 95 | } 96 | 97 | void set( 98 | const std::string& s, 99 | const metrics::attribute::time_point& timestamp = metrics::attribute::clock::now() 100 | ) 101 | { 102 | HANDY_ATTRIBUTE_SET_STRING(name.substr(), s, timestamp); 103 | } 104 | 105 | private: 106 | const std::string name; 107 | }; 108 | 109 | }} // namespace handystats::measuring_points 110 | 111 | #endif // HANDYSTATS_MEASURING_POINTS_ATTRIBUTE_PROXY_HPP_ 112 | -------------------------------------------------------------------------------- /include/handystats/measuring_points/counter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDY_COUNTER_MEASURING_POINTS_H_ 19 | #define HANDY_COUNTER_MEASURING_POINTS_H_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | HANDYSTATS_EXTERN_C 29 | void handystats_counter_init( 30 | const char* counter_name, 31 | const int64_t init_value 32 | ); 33 | 34 | HANDYSTATS_EXTERN_C 35 | void handystats_counter_increment( 36 | const char* counter_name, 37 | const int64_t value 38 | ); 39 | 40 | HANDYSTATS_EXTERN_C 41 | void handystats_counter_decrement( 42 | const char* counter_name, 43 | const int64_t value 44 | ); 45 | 46 | HANDYSTATS_EXTERN_C 47 | void handystats_counter_change( 48 | const char* counter_name, 49 | const int64_t value 50 | ); 51 | 52 | 53 | #ifndef __cplusplus 54 | #ifndef HANDYSTATS_DISABLE 55 | 56 | #define HANDY_COUNTER_INIT(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_counter_init, __VA_ARGS__) 57 | 58 | #define HANDY_COUNTER_INCREMENT(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_counter_increment, __VA_ARGS__) 59 | 60 | #define HANDY_COUNTER_DECREMENT(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_counter_decrement, __VA_ARGS__) 61 | 62 | #define HANDY_COUNTER_CHANGE(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_counter_change, __VA_ARGS__) 63 | 64 | #else 65 | 66 | #define HANDY_COUNTER_INIT(...) 67 | 68 | #define HANDY_COUNTER_INCREMENT(...) 69 | 70 | #define HANDY_COUNTER_DECREMENT(...) 71 | 72 | #define HANDY_COUNTER_CHANGE(...) 73 | 74 | #endif 75 | 76 | struct handystats_scoped_counter_helper { 77 | const char* counter_name; 78 | const int64_t delta_value; 79 | }; 80 | 81 | static inline void handystats_scoped_counter_cleanup(struct handystats_scoped_counter_helper* scoped_counter) { 82 | HANDY_COUNTER_DECREMENT(scoped_counter->counter_name, scoped_counter->delta_value); 83 | } 84 | 85 | #define C_UNIQUE_SCOPED_COUNTER_NAME BOOST_PP_LIST_CAT((C_HANDY_SCOPED_COUNTER_VAR_, (__LINE__, BOOST_PP_NIL))) 86 | 87 | #ifndef HANDYSTATS_DISABLE 88 | 89 | #define HANDY_COUNTER_SCOPE(counter_name, delta_value) \ 90 | BOOST_PP_EXPAND( HANDY_PP_TUPLE_REM() \ 91 | BOOST_PP_IF( \ 92 | HANDY_PP_IS_TUPLE(counter_name), \ 93 | ( \ 94 | HANDY_PP_METRIC_NAME_BUFFER_SET(counter_name); \ 95 | struct handystats_scoped_counter_helper C_UNIQUE_SCOPED_COUNTER_NAME __attribute__((cleanup(handystats_scoped_counter_cleanup))) = \ 96 | {HANDY_PP_METRIC_NAME_BUFFER_VAR, delta_value}; \ 97 | HANDY_COUNTER_INCREMENT(HANDY_PP_METRIC_NAME_BUFFER_VAR, delta_value) \ 98 | ), \ 99 | ( \ 100 | struct handystats_scoped_counter_helper C_UNIQUE_SCOPED_COUNTER_NAME __attribute__((cleanup(handystats_scoped_counter_cleanup))) = \ 101 | {counter_name, delta_value}; \ 102 | HANDY_COUNTER_INCREMENT(counter_name, delta_value) \ 103 | ) \ 104 | ) \ 105 | ) 106 | 107 | #else 108 | 109 | #define HANDY_COUNTER_SCOPE(...) 110 | 111 | #endif 112 | 113 | #endif 114 | 115 | #endif // HANDYSTATS_COUNTER_MEASURING_POINTS_H_ 116 | -------------------------------------------------------------------------------- /include/handystats/measuring_points/counter_proxy.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_MEASURING_POINTS_COUNTER_PROXY_HPP_ 19 | #define HANDYSTATS_MEASURING_POINTS_COUNTER_PROXY_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | 27 | namespace handystats { namespace measuring_points { 28 | 29 | class counter_proxy { 30 | public: 31 | /* 32 | * Ctors without sending init event 33 | */ 34 | counter_proxy(const std::string& name) 35 | : name(name) 36 | {} 37 | 38 | counter_proxy(const char* name) 39 | : name(name) 40 | {} 41 | 42 | /* 43 | * Ctors with init parameters 44 | */ 45 | counter_proxy(const std::string& name, 46 | const metrics::counter::value_type& init_value, 47 | const metrics::counter::time_point& timestamp = metrics::counter::clock::now() 48 | ) 49 | : name(name) 50 | { 51 | HANDY_COUNTER_INIT(name.substr(), init_value, timestamp); 52 | } 53 | 54 | counter_proxy(const char* name, 55 | const metrics::counter::value_type& init_value, 56 | const metrics::counter::time_point& timestamp = metrics::counter::clock::now() 57 | ) 58 | : name(name) 59 | { 60 | HANDY_COUNTER_INIT(this->name.substr(), init_value, timestamp); 61 | } 62 | 63 | /* 64 | * Proxy init event 65 | */ 66 | void init( 67 | const metrics::counter::value_type& init_value = metrics::counter::value_type(), 68 | const metrics::counter::time_point& timestamp = metrics::counter::clock::now() 69 | ) 70 | { 71 | HANDY_COUNTER_INIT(name.substr(), init_value, timestamp); 72 | } 73 | 74 | /* 75 | * Proxy increment event 76 | */ 77 | void increment( 78 | const metrics::counter::value_type& value = 1, 79 | const metrics::counter::time_point& timestamp = metrics::counter::clock::now() 80 | ) 81 | { 82 | HANDY_COUNTER_INCREMENT(name.substr(), value, timestamp); 83 | } 84 | 85 | /* 86 | * Proxy decrement event 87 | */ 88 | void decrement( 89 | const metrics::counter::value_type& value = 1, 90 | const metrics::counter::time_point& timestamp = metrics::counter::clock::now() 91 | ) 92 | { 93 | HANDY_COUNTER_DECREMENT(name.substr(), value, timestamp); 94 | } 95 | 96 | /* 97 | * Proxy change event 98 | */ 99 | void change( 100 | const metrics::counter::value_type& value, 101 | const metrics::counter::time_point& timestamp = metrics::counter::clock::now() 102 | ) 103 | { 104 | HANDY_COUNTER_CHANGE(name.substr(), value, timestamp); 105 | } 106 | 107 | private: 108 | const std::string name; 109 | }; 110 | 111 | }} // namespace handystats::measuring_points::proxy 112 | 113 | #endif // HANDYSTATS_MEASURING_POINTS_COUNTER_PROXY_HPP_ 114 | -------------------------------------------------------------------------------- /include/handystats/measuring_points/gauge.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDY_GAUGE_MEASURING_POINTS_H_ 19 | #define HANDY_GAUGE_MEASURING_POINTS_H_ 20 | 21 | #include 22 | #include 23 | 24 | HANDYSTATS_EXTERN_C 25 | void handystats_gauge_init( 26 | const char* gauge_name, 27 | const double init_value 28 | ); 29 | 30 | HANDYSTATS_EXTERN_C 31 | void handystats_gauge_set( 32 | const char* gauge_name, 33 | const double value 34 | ); 35 | 36 | 37 | #ifndef __cplusplus 38 | #ifndef HANDYSTATS_DISABLE 39 | 40 | #define HANDY_GAUGE_INIT(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_gauge_init, __VA_ARGS__) 41 | 42 | #define HANDY_GAUGE_SET(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_gauge_set, __VA_ARGS__) 43 | 44 | #else 45 | 46 | #define HANDY_GAUGE_INIT(...) 47 | 48 | #define HANDY_GAUGE_SET(...) 49 | 50 | #endif 51 | 52 | #endif 53 | 54 | #endif // HANDYSTATS_GAUGE_MEASURING_POINTS_H_ 55 | -------------------------------------------------------------------------------- /include/handystats/measuring_points/gauge.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_GAUGE_MEASURING_POINTS_HPP_ 19 | #define HANDYSTATS_GAUGE_MEASURING_POINTS_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | 27 | namespace handystats { namespace measuring_points { 28 | 29 | void gauge_init( 30 | std::string&& gauge_name, 31 | const handystats::metrics::gauge::value_type& init_value, 32 | const handystats::metrics::gauge::time_point& timestamp = handystats::metrics::gauge::clock::now() 33 | ); 34 | 35 | void gauge_set( 36 | std::string&& gauge_name, 37 | const handystats::metrics::gauge::value_type& value, 38 | const handystats::metrics::gauge::time_point& timestamp = handystats::metrics::gauge::clock::now() 39 | ); 40 | 41 | }} // namespace handystats::measuring_points 42 | 43 | 44 | #ifndef HANDYSTATS_DISABLE 45 | 46 | #define HANDY_GAUGE_INIT(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats::measuring_points::gauge_init, __VA_ARGS__) 47 | 48 | #define HANDY_GAUGE_SET(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats::measuring_points::gauge_set, __VA_ARGS__) 49 | 50 | #else 51 | 52 | #define HANDY_GAUGE_INIT(...) 53 | 54 | #define HANDY_GAUGE_SET(...) 55 | 56 | #endif 57 | 58 | #endif // HANDYSTATS_GAUGE_MEASURING_POINTS_HPP_ 59 | -------------------------------------------------------------------------------- /include/handystats/measuring_points/gauge_proxy.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_MEASURING_POINTS_GAUGE_PROXY_HPP_ 19 | #define HANDYSTATS_MEASURING_POINTS_GAUGE_PROXY_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | 27 | namespace handystats { namespace measuring_points { 28 | 29 | class gauge_proxy { 30 | public: 31 | /* 32 | * Ctors without sending init event 33 | */ 34 | gauge_proxy(const std::string& name) 35 | : name(name) 36 | {} 37 | 38 | gauge_proxy(const char* name) 39 | : name(name) 40 | {} 41 | 42 | /* 43 | * Ctors with init parameters 44 | */ 45 | gauge_proxy(const std::string& name, 46 | const metrics::gauge::value_type& init_value, 47 | const metrics::gauge::time_point& timestamp = metrics::gauge::clock::now() 48 | ) 49 | : name(name) 50 | { 51 | HANDY_GAUGE_INIT(name.substr(), init_value, timestamp); 52 | } 53 | 54 | gauge_proxy(const char* name, 55 | const metrics::gauge::value_type& init_value, 56 | const metrics::gauge::time_point& timestamp = metrics::gauge::clock::now() 57 | ) 58 | : name(name) 59 | { 60 | HANDY_GAUGE_INIT(this->name.substr(), init_value, timestamp); 61 | } 62 | 63 | /* 64 | * Proxy init event 65 | */ 66 | void init( 67 | const metrics::gauge::value_type& init_value, 68 | const metrics::gauge::time_point& timestamp = metrics::gauge::clock::now() 69 | ) 70 | { 71 | HANDY_GAUGE_INIT(name.substr(), init_value, timestamp); 72 | } 73 | 74 | /* 75 | * Proxy set event 76 | */ 77 | void set( 78 | const metrics::gauge::value_type& value, 79 | const metrics::gauge::time_point& timestamp = metrics::gauge::clock::now() 80 | ) 81 | { 82 | HANDY_GAUGE_SET(name.substr(), value, timestamp); 83 | } 84 | 85 | private: 86 | const std::string name; 87 | }; 88 | 89 | }} // namespace handystats::measuring_points 90 | 91 | #endif // HANDYSTATS_MEASURING_POINTS_GAUGE_PROXY_HPP_ 92 | -------------------------------------------------------------------------------- /include/handystats/measuring_points/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDY_TIMER_MEASURING_POINTS_H_ 19 | #define HANDY_TIMER_MEASURING_POINTS_H_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | HANDYSTATS_EXTERN_C 30 | void handystats_timer_init( 31 | const char* timer_name, 32 | const uint64_t instance_id 33 | ); 34 | 35 | HANDYSTATS_EXTERN_C 36 | void handystats_timer_start( 37 | const char* timer_name, 38 | const uint64_t instance_id 39 | ); 40 | 41 | HANDYSTATS_EXTERN_C 42 | void handystats_timer_stop( 43 | const char* timer_name, 44 | const uint64_t instance_id 45 | ); 46 | 47 | HANDYSTATS_EXTERN_C 48 | void handystats_timer_discard( 49 | const char* timer_name, 50 | const uint64_t instance_id 51 | ); 52 | 53 | HANDYSTATS_EXTERN_C 54 | void handystats_timer_heartbeat( 55 | const char* timer_name, 56 | const uint64_t instance_id 57 | ); 58 | 59 | HANDYSTATS_EXTERN_C 60 | void handystats_timer_set( 61 | const char* timer_name, 62 | const int64_t measurement 63 | ); 64 | 65 | #ifndef __cplusplus 66 | #ifndef HANDYSTATS_DISABLE 67 | 68 | #define HANDY_TIMER_INIT(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_timer_init, __VA_ARGS__) 69 | 70 | #define HANDY_TIMER_START(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_timer_start, __VA_ARGS__) 71 | 72 | #define HANDY_TIMER_STOP(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_timer_stop, __VA_ARGS__) 73 | 74 | #define HANDY_TIMER_DISCARD(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_timer_discard, __VA_ARGS__) 75 | 76 | #define HANDY_TIMER_HEARTBEAT(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_timer_heartbeat, __VA_ARGS__) 77 | 78 | #define HANDY_TIMER_SET(...) HANDY_PP_MEASURING_POINT_WRAPPER(handystats_timer_set, __VA_ARGS__) 79 | 80 | #else 81 | 82 | #define HANDY_TIMER_INIT(...) 83 | 84 | #define HANDY_TIMER_START(...) 85 | 86 | #define HANDY_TIMER_STOP(...) 87 | 88 | #define HANDY_TIMER_DISCARD(...) 89 | 90 | #define HANDY_TIMER_HEARTBEAT(...) 91 | 92 | #define HANDY_TIMER_SET(...) 93 | 94 | #endif 95 | 96 | struct handystats_scoped_timer_helper { 97 | const char* timer_name; 98 | const int64_t start_time; 99 | }; 100 | 101 | static inline void handystats_scoped_timer_cleanup(struct handystats_scoped_timer_helper* scoped_timer) { 102 | int64_t end_time = handystats_now(); 103 | HANDY_TIMER_SET(scoped_timer->timer_name, end_time - scoped_timer->start_time); 104 | } 105 | 106 | #define C_UNIQUE_SCOPED_TIMER_NAME BOOST_PP_LIST_CAT((C_HANDY_SCOPED_TIMER_VAR_, (__LINE__, BOOST_PP_NIL))) 107 | 108 | #ifndef HANDYSTATS_DISABLE 109 | 110 | #define HANDY_TIMER_SCOPE(timer_name) \ 111 | BOOST_PP_EXPAND( HANDY_PP_TUPLE_REM() \ 112 | BOOST_PP_IF( \ 113 | HANDY_PP_IS_TUPLE(timer_name), \ 114 | ( \ 115 | HANDY_PP_METRIC_NAME_BUFFER_SET(timer_name); \ 116 | struct handystats_scoped_timer_helper \ 117 | C_UNIQUE_SCOPED_TIMER_NAME __attribute__((cleanup(handystats_scoped_timer_cleanup))) = \ 118 | {HANDY_PP_METRIC_NAME_BUFFER_VAR, handystats_now()} \ 119 | ), \ 120 | ( \ 121 | struct handystats_scoped_timer_helper \ 122 | C_UNIQUE_SCOPED_TIMER_NAME __attribute__((cleanup(handystats_scoped_timer_cleanup))) = \ 123 | {timer_name, handystats_now()} \ 124 | ) \ 125 | ) \ 126 | ) 127 | 128 | #else 129 | 130 | #define HANDY_TIMER_SCOPE(...) 131 | 132 | #endif 133 | 134 | #endif 135 | 136 | #endif // HANDYSTATS_TIMER_MEASURING_POINTS_H_ 137 | -------------------------------------------------------------------------------- /include/handystats/measuring_points/timer_proxy.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_MEASURING_POINTS_TIMER_PROXY_HPP_ 19 | #define HANDYSTATS_MEASURING_POINTS_TIMER_PROXY_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | 27 | namespace handystats { namespace measuring_points { 28 | 29 | class timer_proxy { 30 | public: 31 | /* 32 | * Ctors without sending init event 33 | */ 34 | timer_proxy(const std::string& name, 35 | const metrics::timer::instance_id_type& instance_id = metrics::timer::DEFAULT_INSTANCE_ID 36 | ) 37 | : name(name) 38 | , instance_id(instance_id) 39 | {} 40 | 41 | timer_proxy(const char* name, 42 | const metrics::timer::instance_id_type& instance_id = metrics::timer::DEFAULT_INSTANCE_ID 43 | ) 44 | : name(name) 45 | , instance_id(instance_id) 46 | {} 47 | 48 | /* 49 | * Proxy init event 50 | */ 51 | void init( 52 | const metrics::timer::instance_id_type& instance_id = metrics::timer::DEFAULT_INSTANCE_ID, 53 | const metrics::timer::time_point& timestamp = metrics::timer::clock::now() 54 | ) 55 | { 56 | HANDY_TIMER_INIT(name.substr(), choose_instance_id(instance_id), timestamp); 57 | } 58 | 59 | /* 60 | * Proxy start event 61 | */ 62 | void start( 63 | const metrics::timer::instance_id_type& instance_id = metrics::timer::DEFAULT_INSTANCE_ID, 64 | const metrics::timer::time_point& timestamp = metrics::timer::clock::now() 65 | ) 66 | { 67 | HANDY_TIMER_START(name.substr(), choose_instance_id(instance_id), timestamp); 68 | } 69 | 70 | /* 71 | * Proxy stop event 72 | */ 73 | void stop( 74 | const metrics::timer::instance_id_type& instance_id = metrics::timer::DEFAULT_INSTANCE_ID, 75 | const metrics::timer::time_point& timestamp = metrics::timer::clock::now() 76 | ) 77 | { 78 | HANDY_TIMER_STOP(name.substr(), choose_instance_id(instance_id), timestamp); 79 | } 80 | 81 | /* 82 | * Proxy discard event 83 | */ 84 | void discard( 85 | const metrics::timer::instance_id_type& instance_id = metrics::timer::DEFAULT_INSTANCE_ID, 86 | const metrics::timer::time_point& timestamp = metrics::timer::clock::now() 87 | ) 88 | { 89 | HANDY_TIMER_DISCARD(name.substr(), choose_instance_id(instance_id), timestamp); 90 | } 91 | 92 | /* 93 | * Proxy heartbeat event 94 | */ 95 | void heartbeat( 96 | const metrics::timer::instance_id_type& instance_id = metrics::timer::DEFAULT_INSTANCE_ID, 97 | const metrics::timer::time_point& timestamp = metrics::timer::clock::now() 98 | ) 99 | { 100 | HANDY_TIMER_HEARTBEAT(name.substr(), choose_instance_id(instance_id), timestamp); 101 | } 102 | 103 | /* 104 | * Proxy set event 105 | */ 106 | void set( 107 | const metrics::timer::value_type& measurement, 108 | const metrics::timer::time_point& timestamp = metrics::timer::clock::now() 109 | ) 110 | { 111 | HANDY_TIMER_SET(name.substr(), measurement, timestamp); 112 | } 113 | 114 | private: 115 | const std::string name; 116 | const metrics::timer::instance_id_type instance_id; 117 | 118 | metrics::timer::instance_id_type choose_instance_id(const metrics::timer::instance_id_type& instance_id) { 119 | if (this->instance_id != metrics::timer::DEFAULT_INSTANCE_ID) { 120 | return this->instance_id; 121 | } 122 | else { 123 | return instance_id; 124 | } 125 | } 126 | }; 127 | 128 | }} // namespace handystats::measuring_points 129 | 130 | #endif // HANDYSTATS_MEASURING_POINTS_TIMER_PROXY_HPP_ 131 | -------------------------------------------------------------------------------- /include/handystats/metrics.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_METRICS_HPP_ 19 | #define HANDYSTATS_METRICS_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | namespace handystats { namespace metrics { 29 | 30 | // Generic metric 31 | typedef boost::variant < 32 | counter, 33 | gauge, 34 | timer, 35 | attribute 36 | > metric_variant; 37 | 38 | 39 | // Generic metric pointer 40 | typedef boost::variant < 41 | counter*, 42 | gauge*, 43 | timer*, 44 | attribute* 45 | > metric_ptr_variant; 46 | 47 | 48 | // Generic metrics index 49 | enum metric_index { 50 | COUNTER = 0, 51 | GAUGE, 52 | TIMER, 53 | ATTRIBUTE 54 | }; 55 | 56 | }} // namespace handystats::metrics 57 | 58 | #endif // HANDYSTATS_METRICS_HPP_ 59 | -------------------------------------------------------------------------------- /include/handystats/metrics/attribute.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_METRICS_ATTRIBUTE_HPP_ 19 | #define HANDYSTATS_METRICS_ATTRIBUTE_HPP_ 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | 28 | namespace handystats { namespace metrics { 29 | 30 | struct attribute 31 | { 32 | typedef boost::variant < 33 | bool, 34 | int, 35 | unsigned, 36 | int64_t, 37 | uint64_t, 38 | double, 39 | std::string 40 | > 41 | value_type; 42 | 43 | enum value_index { 44 | BOOL = 0, 45 | INT, 46 | UINT, 47 | INT64, 48 | UINT64, 49 | DOUBLE, 50 | STRING 51 | }; 52 | 53 | typedef chrono::tsc_clock clock; 54 | typedef chrono::time_point time_point; 55 | 56 | attribute(); 57 | 58 | void set(const value_type& value); 59 | 60 | // support for primitive types (as in rapidjson) 61 | void set(const bool& b); 62 | void set(const int& i); 63 | void set(const unsigned& u); 64 | void set(const int64_t& i64); 65 | void set(const uint64_t& u64); 66 | void set(const double& d); 67 | 68 | // support for strings 69 | void set(const char* s); 70 | void set(const std::string& s); 71 | 72 | const value_type& value() const; 73 | 74 | private: 75 | value_type m_value; 76 | 77 | }; // struct attribute 78 | 79 | }} // namespace handystats::metrics 80 | 81 | 82 | #endif // HANDYSTATS_METRICS_ATTRIBUTE_HPP_ 83 | -------------------------------------------------------------------------------- /include/handystats/metrics/counter.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_METRICS_COUNTER_HPP_ 19 | #define HANDYSTATS_METRICS_COUNTER_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | namespace handystats { namespace metrics { 30 | 31 | struct counter 32 | { 33 | typedef int64_t value_type; 34 | typedef chrono::tsc_clock clock; 35 | typedef chrono::time_point time_point; 36 | 37 | counter(const config::metrics::counter& opts = config::metrics::counter()); 38 | 39 | void init(const value_type& value = 0, const time_point& timestamp = clock::now()); 40 | void increment(const value_type& value = 1, const time_point& timestamp = clock::now()); 41 | void decrement(const value_type& value = 1, const time_point& timestamp = clock::now()); 42 | 43 | void update_statistics(const time_point& timestamp = clock::now()); 44 | 45 | const statistics& values() const; 46 | 47 | private: 48 | statistics m_values; 49 | 50 | value_type m_value; 51 | time_point m_timestamp; 52 | 53 | }; // struct counter 54 | 55 | }} // namespace handystats::metrics 56 | 57 | 58 | #endif // HANDYSTATS_METRICS_COUNTER_HPP_ 59 | -------------------------------------------------------------------------------- /include/handystats/metrics/gauge.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_METRICS_GAUGE_HPP_ 19 | #define HANDYSTATS_METRICS_GAUGE_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | namespace handystats { namespace metrics { 28 | 29 | struct gauge 30 | { 31 | typedef double value_type; 32 | typedef chrono::tsc_clock clock; 33 | typedef chrono::time_point time_point; 34 | 35 | gauge(const config::metrics::gauge& opts = config::metrics::gauge()); 36 | 37 | void set(const value_type& value, const time_point& timestamp = clock::now()); 38 | 39 | void update_statistics(const time_point& timestamp = clock::now()); 40 | 41 | const statistics& values() const; 42 | 43 | private: 44 | statistics m_values; 45 | 46 | }; // struct gauge 47 | 48 | }} // namespace handystats::metrics 49 | 50 | 51 | #endif // HANDYSTATS_METRICS_GAUGE_HPP_ 52 | -------------------------------------------------------------------------------- /include/handystats/metrics/timer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_METRICS_TIMER_HPP_ 19 | #define HANDYSTATS_METRICS_TIMER_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | namespace handystats { namespace metrics { 32 | 33 | struct timer 34 | { 35 | typedef chrono::duration value_type; 36 | static const chrono::time_unit value_unit; 37 | 38 | typedef chrono::tsc_clock clock; 39 | typedef chrono::time_point time_point; 40 | 41 | typedef uint64_t instance_id_type; 42 | 43 | static const instance_id_type DEFAULT_INSTANCE_ID; 44 | 45 | struct instance_state { 46 | time_point start_timestamp; 47 | time_point heartbeat_timestamp; 48 | 49 | instance_state() 50 | : start_timestamp() 51 | , heartbeat_timestamp() 52 | { 53 | } 54 | 55 | bool expired(const chrono::duration& idle_timeout, const time_point& timestamp = clock::now()) { 56 | return (timestamp > heartbeat_timestamp) && (timestamp - heartbeat_timestamp > idle_timeout); 57 | } 58 | }; 59 | 60 | timer(const config::metrics::timer& timer_opts = config::metrics::timer()); 61 | 62 | void start( 63 | const instance_id_type& instance_id = DEFAULT_INSTANCE_ID, 64 | const time_point& timestamp = clock::now() 65 | ); 66 | 67 | void stop( 68 | const instance_id_type& instance_id = DEFAULT_INSTANCE_ID, 69 | const time_point& timestamp = clock::now() 70 | ); 71 | 72 | void heartbeat( 73 | const instance_id_type& instance_id = DEFAULT_INSTANCE_ID, 74 | const time_point& timestamp = clock::now() 75 | ); 76 | 77 | void discard( 78 | const instance_id_type& instance_id = DEFAULT_INSTANCE_ID, 79 | const time_point& timestamp = clock::now() 80 | ); 81 | 82 | void set( 83 | const value_type& measurement, 84 | const time_point& timestamp = clock::now() 85 | ); 86 | 87 | void check_idle_timeout( 88 | const time_point& timestamp = clock::now(), 89 | const bool& force = false 90 | ); 91 | 92 | void update_statistics(const time_point& timestamp = clock::now()); 93 | 94 | const statistics& values() const; 95 | 96 | private: 97 | chrono::duration m_idle_timeout; 98 | 99 | statistics m_values; 100 | 101 | std::unordered_map m_instances; 102 | 103 | time_point m_idle_check_timestamp; 104 | 105 | }; // struct timer 106 | 107 | }} // namespace handystats::metrics 108 | 109 | 110 | #endif // HANDYSTATS_METRICS_TIMER_HPP_ 111 | -------------------------------------------------------------------------------- /include/handystats/metrics_dump.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_METRICS_DUMP_HPP_ 19 | #define HANDYSTATS_METRICS_DUMP_HPP_ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | const std::shared_ptr < 28 | const std::map < 29 | std::string, handystats::metrics::metric_variant 30 | > 31 | > 32 | HANDY_METRICS_DUMP(); 33 | 34 | #endif // HANDYSTATS_METRICS_DUMP_HPP_ 35 | -------------------------------------------------------------------------------- /src/chrono/system_clock.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | 22 | namespace handystats { namespace chrono { 23 | 24 | time_point system_clock::now() { 25 | struct timespec ts; 26 | clock_gettime(CLOCK_REALTIME, &ts); 27 | 28 | return time_point(duration(ts.tv_sec * 1000ull * 1000ull * 1000ull + ts.tv_nsec, time_unit::NSEC), clock_type::SYSTEM); 29 | } 30 | 31 | }} // namespace handystats::chrono 32 | -------------------------------------------------------------------------------- /src/config/core.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include "config/core_impl.hpp" 19 | 20 | namespace handystats { namespace config { 21 | 22 | core::core() 23 | : enable(true) 24 | {} 25 | 26 | void core::configure(const rapidjson::Value& config) { 27 | if (!config.IsObject()) { 28 | return; 29 | } 30 | 31 | if (config.HasMember("enable")) { 32 | const rapidjson::Value& enable = config["enable"]; 33 | if (enable.IsBool()) { 34 | this->enable = enable.GetBool(); 35 | } 36 | } 37 | } 38 | 39 | }} // namespace handystats::config 40 | -------------------------------------------------------------------------------- /src/config/core_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_CONFIG_CORE_IMPL_HPP_ 19 | #define HANDYSTATS_CONFIG_CORE_IMPL_HPP_ 20 | 21 | #include 22 | 23 | namespace handystats { namespace config { 24 | 25 | struct core { 26 | bool enable; 27 | 28 | core(); 29 | void configure(const rapidjson::Value& config); 30 | }; 31 | 32 | }} // namespace handystats::config 33 | 34 | #endif // HANDYSTATS_CONFIG_CORE_HPP_ 35 | -------------------------------------------------------------------------------- /src/config/metrics/counter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | #include "config_impl.hpp" 21 | 22 | namespace handystats { namespace config { namespace metrics { 23 | 24 | counter::counter() 25 | : values(statistics()) 26 | { 27 | } 28 | 29 | void configure(counter& obj, const rapidjson::Value& config) { 30 | if (!config.IsObject()) { 31 | return; 32 | } 33 | 34 | configure(obj.values, config); 35 | } 36 | 37 | }}} // namespace handystats::config::metrics 38 | -------------------------------------------------------------------------------- /src/config/metrics/gauge.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | #include "config_impl.hpp" 21 | 22 | namespace handystats { namespace config { namespace metrics { 23 | 24 | gauge::gauge() 25 | : values(statistics()) 26 | { 27 | } 28 | 29 | void configure(gauge& obj, const rapidjson::Value& config) { 30 | if (!config.IsObject()) { 31 | return; 32 | } 33 | 34 | configure(obj.values, config); 35 | } 36 | 37 | }}} // namespace handystats::config::metrics 38 | -------------------------------------------------------------------------------- /src/config/metrics/timer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | 22 | #include "config_impl.hpp" 23 | 24 | namespace handystats { namespace config { namespace metrics { 25 | 26 | timer::timer() 27 | : idle_timeout(10, chrono::time_unit::SEC) 28 | , values(statistics()) 29 | { 30 | } 31 | 32 | void configure(timer& obj, const rapidjson::Value& config) { 33 | if (!config.IsObject()) { 34 | return; 35 | } 36 | 37 | if (config.HasMember("idle-timeout")) { 38 | const rapidjson::Value& idle_timeout = config["idle-timeout"]; 39 | if (idle_timeout.IsUint64()) { 40 | obj.idle_timeout = chrono::duration(idle_timeout.GetUint64(), chrono::time_unit::MSEC); 41 | } 42 | } 43 | 44 | configure(obj.values, config); 45 | } 46 | 47 | }}} // namespace handystats::config::metrics 48 | -------------------------------------------------------------------------------- /src/config/metrics_dump.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include "config/metrics_dump_impl.hpp" 19 | 20 | namespace handystats { namespace config { 21 | 22 | metrics_dump::metrics_dump() 23 | : interval(750, chrono::time_unit::MSEC) 24 | {} 25 | 26 | void metrics_dump::configure(const rapidjson::Value& config) { 27 | if (!config.IsObject()) { 28 | return; 29 | } 30 | 31 | if (config.HasMember("interval")) { 32 | const rapidjson::Value& interval = config["interval"]; 33 | if (interval.IsUint64()) { 34 | this->interval = chrono::duration(interval.GetUint64(), chrono::time_unit::MSEC); 35 | } 36 | } 37 | } 38 | 39 | }} // namespace handystats::config 40 | -------------------------------------------------------------------------------- /src/config/metrics_dump_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_CONFIG_METRICS_DUMP_IMPL_HPP_ 19 | #define HANDYSTATS_CONFIG_METRICS_DUMP_IMPL_HPP_ 20 | 21 | #include 22 | #include 23 | 24 | namespace handystats { namespace config { 25 | 26 | struct metrics_dump { 27 | chrono::duration interval; 28 | 29 | metrics_dump(); 30 | void configure(const rapidjson::Value& config); 31 | }; 32 | 33 | }} // namespace handystats::config 34 | 35 | #endif // HANDYSTATS_CONFIG_METRICS_DUMP_HPP_ 36 | -------------------------------------------------------------------------------- /src/config/statistics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "config_impl.hpp" 22 | 23 | namespace handystats { namespace config { 24 | 25 | statistics::statistics() 26 | : moving_interval(1, chrono::time_unit::SEC) 27 | , histogram_bins(30) 28 | , tags( 29 | handystats::statistics::tag::value | 30 | handystats::statistics::tag::min | handystats::statistics::tag::max | 31 | handystats::statistics::tag::count | handystats::statistics::tag::sum | handystats::statistics::tag::avg | 32 | handystats::statistics::tag::moving_count | handystats::statistics::tag::moving_sum | handystats::statistics::tag::moving_avg | 33 | handystats::statistics::tag::timestamp 34 | ) 35 | , rate_unit(chrono::time_unit::SEC) 36 | {} 37 | 38 | void configure(statistics& obj, const rapidjson::Value& config) { 39 | if (!config.IsObject()) { 40 | return; 41 | } 42 | 43 | if (config.HasMember("moving-interval")) { 44 | const rapidjson::Value& moving_interval = config["moving-interval"]; 45 | if (moving_interval.IsUint64() && moving_interval.GetUint64() > 0) { 46 | obj.moving_interval = chrono::duration(moving_interval.GetUint64(), chrono::time_unit::MSEC); 47 | } 48 | } 49 | 50 | if (config.HasMember("histogram-bins")) { 51 | const rapidjson::Value& histogram_bins = config["histogram-bins"]; 52 | if (histogram_bins.IsUint64() && histogram_bins.GetUint64() > 0) { 53 | obj.histogram_bins = histogram_bins.GetUint64(); 54 | } 55 | } 56 | 57 | if (config.HasMember("tags")) { 58 | const rapidjson::Value& tags = config["tags"]; 59 | 60 | if (tags.IsArray()) { 61 | obj.tags = handystats::statistics::tag::empty; 62 | for (size_t index = 0; index < tags.Size(); ++index) { 63 | const rapidjson::Value& tag = tags[index]; 64 | if (tag.IsString()) { 65 | obj.tags |= handystats::statistics::tag::from_string(tag.GetString()); 66 | } 67 | } 68 | } 69 | } 70 | 71 | if (config.HasMember("rate-unit")) { 72 | const rapidjson::Value& rate_unit = config["rate-unit"]; 73 | 74 | if (rate_unit.IsString()) { 75 | chrono::time_unit unit = chrono::time_unit::TICK; 76 | if (strcmp(rate_unit.GetString(), "ns") == 0) { 77 | unit = chrono::time_unit::NSEC; 78 | } 79 | else if (strcmp(rate_unit.GetString(), "us") == 0) { 80 | unit = chrono::time_unit::USEC; 81 | } 82 | else if (strcmp(rate_unit.GetString(), "ms") == 0) { 83 | unit = chrono::time_unit::MSEC; 84 | } 85 | else if (strcmp(rate_unit.GetString(), "s") == 0) { 86 | unit = chrono::time_unit::SEC; 87 | } 88 | else if (strcmp(rate_unit.GetString(), "m") == 0) { 89 | unit = chrono::time_unit::MIN; 90 | } 91 | else if (strcmp(rate_unit.GetString(), "h") == 0) { 92 | unit = chrono::time_unit::HOUR; 93 | } 94 | 95 | if (unit != chrono::time_unit::TICK) { 96 | obj.rate_unit = unit; 97 | } 98 | } 99 | } 100 | } 101 | 102 | }} // namespace handystats::config 103 | -------------------------------------------------------------------------------- /src/config_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_CONFIG_IMPL_HPP_ 19 | #define HANDYSTATS_CONFIG_IMPL_HPP_ 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "config/metrics_dump_impl.hpp" 32 | #include "config/core_impl.hpp" 33 | 34 | namespace handystats { namespace config { 35 | 36 | extern statistics statistics_opts; 37 | 38 | namespace metrics { 39 | extern gauge gauge_opts; 40 | extern counter counter_opts; 41 | extern timer timer_opts; 42 | } 43 | 44 | extern metrics_dump metrics_dump_opts; 45 | extern core core_opts; 46 | 47 | extern 48 | std::vector< 49 | std::pair< 50 | std::vector, 51 | rapidjson::Value* 52 | > 53 | > 54 | pattern_opts; 55 | 56 | extern 57 | std::shared_ptr source; 58 | 59 | rapidjson::Value* select_pattern(const std::string&); 60 | 61 | void initialize(); 62 | void finalize(); 63 | 64 | void configure(statistics&, const rapidjson::Value& config); 65 | 66 | namespace metrics { 67 | void configure(gauge&, const rapidjson::Value& config); 68 | void configure(counter&, const rapidjson::Value& config); 69 | void configure(timer&, const rapidjson::Value& config); 70 | } // namespace metrics 71 | 72 | }} // namespace handystats::config 73 | 74 | #endif // HANDYSTATS_CONFIG_IMPL_HPP_ 75 | -------------------------------------------------------------------------------- /src/core.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "events/event_message_impl.hpp" 29 | #include "message_queue_impl.hpp" 30 | #include "internal_impl.hpp" 31 | #include "metrics_dump_impl.hpp" 32 | #include "config_impl.hpp" 33 | 34 | #include "core_impl.hpp" 35 | 36 | namespace handystats { 37 | 38 | std::mutex operation_mutex; 39 | std::atomic enabled_flag(false); 40 | 41 | bool is_enabled() { 42 | return config::core_opts.enable && enabled_flag.load(std::memory_order_acquire); 43 | } 44 | 45 | 46 | chrono::time_point last_message_timestamp; 47 | std::thread processor_thread; 48 | 49 | static void process_message_queue() { 50 | auto* message = message_queue::pop(); 51 | 52 | chrono::time_point timestamp; 53 | 54 | if (message) { 55 | last_message_timestamp = std::max(last_message_timestamp, message->timestamp); 56 | internal::process_event_message(*message); 57 | } 58 | 59 | events::delete_event_message(message); 60 | } 61 | 62 | static void run_processor() noexcept { 63 | char thread_name[16]; 64 | memset(thread_name, 0, sizeof(thread_name)); 65 | 66 | sprintf(thread_name, "handystats"); 67 | 68 | prctl(PR_SET_NAME, thread_name); 69 | 70 | while (is_enabled()) { 71 | if (!message_queue::empty()) { 72 | process_message_queue(); 73 | } 74 | else { 75 | last_message_timestamp = std::max(last_message_timestamp, chrono::tsc_clock::now()); 76 | std::this_thread::sleep_for(std::chrono::microseconds(1000)); 77 | } 78 | 79 | metrics_dump::update(chrono::tsc_clock::now(), last_message_timestamp); 80 | } 81 | } 82 | 83 | void initialize() { 84 | std::lock_guard lock(operation_mutex); 85 | if (enabled_flag.load(std::memory_order_acquire)) { 86 | return; 87 | } 88 | 89 | metrics_dump::initialize(); 90 | internal::initialize(); 91 | message_queue::initialize(); 92 | 93 | if (!config::core_opts.enable) { 94 | return; 95 | } 96 | 97 | enabled_flag.store(true, std::memory_order_release); 98 | 99 | last_message_timestamp = chrono::time_point(); 100 | 101 | processor_thread = std::thread(run_processor); 102 | } 103 | 104 | void finalize() { 105 | std::lock_guard lock(operation_mutex); 106 | enabled_flag.store(false, std::memory_order_release); 107 | 108 | if (processor_thread.joinable()) { 109 | processor_thread.join(); 110 | } 111 | 112 | internal::finalize(); 113 | message_queue::finalize(); 114 | metrics_dump::finalize(); 115 | config::finalize(); 116 | } 117 | 118 | } // namespace handystats 119 | 120 | 121 | extern "C" { 122 | 123 | void handystats_initialize() { 124 | handystats::initialize(); 125 | } 126 | 127 | void handystats_finalize() { 128 | handystats::finalize(); 129 | } 130 | 131 | } // extern "C" 132 | -------------------------------------------------------------------------------- /src/core_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_CORE_IMPL_HPP_ 19 | #define HANDYSTATS_CORE_IMPL_HPP_ 20 | 21 | #include 22 | 23 | namespace handystats { 24 | 25 | extern std::mutex operation_mutex; 26 | 27 | bool is_enabled(); 28 | 29 | } // namespace handystats 30 | 31 | 32 | #endif // HANDYSTATS_CORE_IMPL_HPP_ 33 | -------------------------------------------------------------------------------- /src/cpuid_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_CPUID_IMPL_HPP_ 19 | #define HANDYSTATS_CPUID_IMPL_HPP_ 20 | 21 | #include 22 | #include 23 | 24 | namespace handystats { 25 | 26 | // TSC Support (1 EDX Bit 04) 27 | inline 28 | bool tsc_supported() { 29 | uint32_t eax, ebx, ecx, edx; 30 | 31 | if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx)) { 32 | return false; 33 | } 34 | 35 | return ((edx >> 4) & 1); 36 | } 37 | 38 | // Invariant TSC support (80000007H EDX Bit 08) 39 | static 40 | bool invariant_tsc() { 41 | uint32_t eax, ebx, ecx, edx; 42 | 43 | if (!__get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx)) { 44 | return false; 45 | } 46 | 47 | return ((edx >> 8) & 1); 48 | } 49 | 50 | // RDTSCP Instruction support (80000001H EDX Bit 27) 51 | static 52 | bool rdtscp_supported() { 53 | uint32_t eax, ebx, ecx, edx; 54 | 55 | if (!__get_cpuid(0x80000001, &eax, &ebx, &ecx, &edx)) { 56 | return false; 57 | } 58 | 59 | return ((edx >> 27) & 1); 60 | } 61 | 62 | } // namespace handystats 63 | 64 | #endif // HANDYSTATS_CPUID_IMPL_HPP_ 65 | -------------------------------------------------------------------------------- /src/events/attribute.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | #include "events/attribute_impl.hpp" 21 | 22 | 23 | namespace handystats { namespace events { namespace attribute { 24 | 25 | event_message* create_set_event( 26 | std::string&& attribute_name, 27 | const metrics::attribute::value_type& value, 28 | const metrics::attribute::time_point& timestamp 29 | ) 30 | { 31 | event_message* message = new event_message; 32 | 33 | message->destination_name.swap(attribute_name); 34 | message->destination_type = event_destination_type::ATTRIBUTE; 35 | 36 | message->timestamp = timestamp; 37 | 38 | message->event_type = event_type::SET; 39 | message->event_data = new metrics::attribute::value_type(value); 40 | 41 | return message; 42 | } 43 | 44 | void delete_set_event(event_message* message) { 45 | delete static_cast(message->event_data); 46 | 47 | delete message; 48 | } 49 | 50 | void delete_event(event_message* message) { 51 | switch (message->event_type) { 52 | case event_type::SET: 53 | delete_set_event(message); 54 | break; 55 | } 56 | } 57 | 58 | void process_set_event(metrics::attribute& attribute, const event_message& message) { 59 | const auto& value = *reinterpret_cast(message.event_data); 60 | attribute.set(value); 61 | } 62 | 63 | void process_event(metrics::attribute& attribute, const event_message& message) { 64 | switch (message.event_type) { 65 | case event_type::SET: 66 | process_set_event(attribute, message); 67 | break; 68 | default: 69 | return; 70 | } 71 | } 72 | 73 | 74 | }}} // namespace handystats::events::attribute 75 | -------------------------------------------------------------------------------- /src/events/attribute_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_ATTRIBUTE_EVENT_IMPL_HPP_ 19 | #define HANDYSTATS_ATTRIBUTE_EVENT_IMPL_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include "events/event_message_impl.hpp" 26 | 27 | 28 | namespace handystats { namespace events { namespace attribute { 29 | 30 | namespace event_type { 31 | enum : char { 32 | SET = 0 33 | }; 34 | } // namespace event_type 35 | 36 | /* 37 | * Event creation functions 38 | */ 39 | event_message* create_set_event( 40 | std::string&& attribute_name, 41 | const metrics::attribute::value_type& value, 42 | const metrics::attribute::time_point& timestamp 43 | ); 44 | 45 | /* 46 | * Event destructor 47 | */ 48 | void delete_event(event_message* message); 49 | 50 | 51 | /* 52 | * Event processing function 53 | */ 54 | void process_event(metrics::attribute& counter, const event_message& message); 55 | 56 | }}} // namespace handystats::events::attribute 57 | 58 | 59 | #endif // HANDYSTATS_ATTRIBUTE_EVENT_HPP_ 60 | 61 | -------------------------------------------------------------------------------- /src/events/counter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include "config_impl.hpp" 19 | 20 | #include "events/counter_impl.hpp" 21 | 22 | 23 | namespace handystats { namespace events { namespace counter { 24 | 25 | event_message* create_init_event( 26 | std::string&& counter_name, 27 | const metrics::counter::value_type& init_value, 28 | const metrics::counter::time_point& timestamp 29 | ) 30 | { 31 | event_message* message = new event_message; 32 | 33 | message->destination_name.swap(counter_name); 34 | message->destination_type = event_destination_type::COUNTER; 35 | 36 | message->timestamp = timestamp; 37 | 38 | message->event_type = event_type::INIT; 39 | new (&message->event_data) metrics::counter::value_type(init_value); 40 | 41 | return message; 42 | } 43 | 44 | void delete_init_event(event_message* message) { 45 | delete message; 46 | } 47 | 48 | 49 | event_message* create_increment_event( 50 | std::string&& counter_name, 51 | const metrics::counter::value_type& value, 52 | const metrics::counter::time_point& timestamp 53 | ) 54 | { 55 | event_message* message = new event_message; 56 | 57 | message->destination_name.swap(counter_name); 58 | message->destination_type = event_destination_type::COUNTER; 59 | 60 | message->timestamp = timestamp; 61 | 62 | message->event_type = event_type::INCREMENT; 63 | new (&message->event_data) metrics::counter::value_type(value); 64 | 65 | return message; 66 | } 67 | 68 | void delete_increment_event(event_message* message) { 69 | delete message; 70 | } 71 | 72 | 73 | event_message* create_decrement_event( 74 | std::string&& counter_name, 75 | const metrics::counter::value_type& value, 76 | const metrics::counter::time_point& timestamp 77 | ) 78 | { 79 | event_message* message = new event_message; 80 | 81 | message->destination_name.swap(counter_name); 82 | message->destination_type = event_destination_type::COUNTER; 83 | 84 | message->timestamp = timestamp; 85 | 86 | message->event_type = event_type::DECREMENT; 87 | new (&message->event_data) metrics::counter::value_type(value); 88 | 89 | return message; 90 | } 91 | 92 | void delete_decrement_event(event_message* message) { 93 | delete message; 94 | } 95 | 96 | 97 | void delete_event(event_message* message) { 98 | switch (message->event_type) { 99 | case event_type::INIT: 100 | delete_init_event(message); 101 | break; 102 | case event_type::INCREMENT: 103 | delete_increment_event(message); 104 | break; 105 | case event_type::DECREMENT: 106 | delete_decrement_event(message); 107 | break; 108 | } 109 | } 110 | 111 | 112 | 113 | void process_init_event(metrics::counter& counter, const event_message& message) { 114 | const auto& init_value = reinterpret_cast(message.event_data); 115 | counter = metrics::counter(config::metrics::counter_opts); 116 | counter.init(init_value, message.timestamp); 117 | } 118 | 119 | void process_increment_event(metrics::counter& counter, const event_message& message) { 120 | const auto& incr_value = reinterpret_cast(message.event_data); 121 | counter.increment(incr_value, message.timestamp); 122 | } 123 | 124 | void process_decrement_event(metrics::counter& counter, const event_message& message) { 125 | const auto& decr_value = reinterpret_cast(message.event_data); 126 | counter.decrement(decr_value, message.timestamp); 127 | } 128 | 129 | 130 | void process_event(metrics::counter& counter, const event_message& message) { 131 | switch (message.event_type) { 132 | case event_type::INIT: 133 | process_init_event(counter, message); 134 | break; 135 | case event_type::INCREMENT: 136 | process_increment_event(counter, message); 137 | break; 138 | case event_type::DECREMENT: 139 | process_decrement_event(counter, message); 140 | break; 141 | default: 142 | return; 143 | } 144 | } 145 | 146 | 147 | }}} // namespace handystats::events::counter 148 | 149 | -------------------------------------------------------------------------------- /src/events/counter_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_COUNTER_EVENT_IMPL_HPP_ 19 | #define HANDYSTATS_COUNTER_EVENT_IMPL_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include "events/event_message_impl.hpp" 26 | 27 | 28 | namespace handystats { namespace events { namespace counter { 29 | 30 | namespace event_type { 31 | enum : char { 32 | INIT = 0, 33 | INCREMENT, 34 | DECREMENT 35 | }; 36 | } // namespace event_type 37 | 38 | /* 39 | * Event creation functions 40 | */ 41 | event_message* create_init_event( 42 | std::string&& counter_name, 43 | const metrics::counter::value_type& init_value, 44 | const metrics::counter::time_point& timestamp 45 | ); 46 | 47 | event_message* create_increment_event( 48 | std::string&& counter_name, 49 | const metrics::counter::value_type& value, 50 | const metrics::counter::time_point& timestamp 51 | ); 52 | 53 | event_message* create_decrement_event( 54 | std::string&& counter_name, 55 | const metrics::counter::value_type& value, 56 | const metrics::counter::time_point& timestamp 57 | ); 58 | 59 | 60 | /* 61 | * Event destructor 62 | */ 63 | void delete_event(event_message* message); 64 | 65 | 66 | /* 67 | * Event processing function 68 | */ 69 | void process_event(metrics::counter& counter, const event_message& message); 70 | 71 | }}} // namespace handystats::events::counter 72 | 73 | 74 | #endif // HANDYSTATS_COUNTER_EVENT_HPP_ 75 | -------------------------------------------------------------------------------- /src/events/event_message.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include "events/gauge_impl.hpp" 19 | #include "events/counter_impl.hpp" 20 | #include "events/timer_impl.hpp" 21 | #include "events/attribute_impl.hpp" 22 | 23 | #include "events/event_message_impl.hpp" 24 | 25 | 26 | namespace handystats { namespace events { 27 | 28 | void delete_event_message(event_message* message) { 29 | if (!message) { 30 | return; 31 | } 32 | 33 | switch (message->destination_type) { 34 | case event_destination_type::COUNTER: 35 | counter::delete_event(message); 36 | break; 37 | case event_destination_type::GAUGE: 38 | gauge::delete_event(message); 39 | break; 40 | case event_destination_type::TIMER: 41 | timer::delete_event(message); 42 | break; 43 | case event_destination_type::ATTRIBUTE: 44 | attribute::delete_event(message); 45 | break; 46 | default: 47 | return; 48 | } 49 | } 50 | 51 | }} // namespace handystats::events 52 | -------------------------------------------------------------------------------- /src/events/event_message_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_EVENT_MESSAGE_HPP_ 19 | #define HANDYSTATS_EVENT_MESSAGE_HPP_ 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #include "message_queue_impl.hpp" 27 | 28 | namespace handystats { namespace events { 29 | 30 | namespace event_destination_type { 31 | enum : char { 32 | COUNTER = 0, 33 | GAUGE, 34 | TIMER, 35 | ATTRIBUTE 36 | }; 37 | } 38 | 39 | struct event_message : message_queue::node 40 | { 41 | char destination_type; 42 | char event_type; 43 | std::string destination_name; 44 | 45 | chrono::time_point timestamp; 46 | 47 | void* event_data; 48 | }; 49 | 50 | void delete_event_message(event_message* message); 51 | 52 | struct event_message_deleter { 53 | void operator() (event_message* message) const { 54 | delete_event_message(message); 55 | } 56 | }; 57 | 58 | }} // namespace handystats::events 59 | 60 | #endif // HANDYSTATS_EVENT_MESSAGE_HPP_ 61 | -------------------------------------------------------------------------------- /src/events/gauge.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include "config_impl.hpp" 19 | 20 | #include "events/gauge_impl.hpp" 21 | 22 | 23 | namespace handystats { namespace events { namespace gauge { 24 | 25 | event_message* create_init_event( 26 | std::string&& gauge_name, 27 | const metrics::gauge::value_type& init_value, 28 | const metrics::gauge::time_point& timestamp 29 | ) 30 | { 31 | event_message* message = new event_message; 32 | 33 | message->destination_name.swap(gauge_name); 34 | message->destination_type = event_destination_type::GAUGE; 35 | 36 | message->timestamp = timestamp; 37 | 38 | message->event_type = event_type::INIT; 39 | new (&message->event_data) metrics::gauge::value_type(init_value); 40 | 41 | return message; 42 | } 43 | 44 | void delete_init_event(event_message* message) { 45 | delete message; 46 | } 47 | 48 | 49 | event_message* create_set_event( 50 | std::string&& gauge_name, 51 | const metrics::gauge::value_type& value, 52 | const metrics::gauge::time_point& timestamp 53 | ) 54 | { 55 | event_message* message = new event_message; 56 | 57 | message->destination_name.swap(gauge_name); 58 | message->destination_type = event_destination_type::GAUGE; 59 | 60 | message->timestamp = timestamp; 61 | 62 | message->event_type = event_type::SET; 63 | new (&message->event_data) metrics::gauge::value_type(value); 64 | 65 | return message; 66 | } 67 | 68 | void delete_set_event(event_message* message) { 69 | delete message; 70 | } 71 | 72 | 73 | void delete_event(event_message* message) { 74 | switch (message->event_type) { 75 | case event_type::INIT: 76 | delete_init_event(message); 77 | break; 78 | case event_type::SET: 79 | delete_set_event(message); 80 | break; 81 | } 82 | } 83 | 84 | 85 | 86 | void process_init_event(metrics::gauge& gauge, const event_message& message) { 87 | const auto& init_value = *reinterpret_cast(&message.event_data); 88 | gauge = metrics::gauge(config::metrics::gauge_opts); 89 | gauge.set(init_value, message.timestamp); 90 | } 91 | 92 | void process_set_event(metrics::gauge& gauge, const event_message& message) { 93 | const auto& value = *reinterpret_cast(&message.event_data); 94 | gauge.set(value, message.timestamp); 95 | } 96 | 97 | 98 | void process_event(metrics::gauge& gauge, const event_message& message) { 99 | switch (message.event_type) { 100 | case event_type::INIT: 101 | process_init_event(gauge, message); 102 | break; 103 | case event_type::SET: 104 | process_set_event(gauge, message); 105 | break; 106 | default: 107 | return; 108 | } 109 | } 110 | 111 | 112 | }}} // namespace handystats::events::gauge 113 | 114 | -------------------------------------------------------------------------------- /src/events/gauge_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_GAUGE_EVENT_IMPL_HPP_ 19 | #define HANDYSTATS_GAUGE_EVENT_IMPL_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include "events/event_message_impl.hpp" 26 | 27 | 28 | namespace handystats { namespace events { namespace gauge { 29 | 30 | namespace event_type { 31 | enum : char { 32 | INIT = 0, 33 | SET 34 | }; 35 | } // namespace event_type 36 | 37 | /* 38 | * Event creation functions 39 | */ 40 | event_message* create_init_event( 41 | std::string&& gauge_name, 42 | const metrics::gauge::value_type& init_value, 43 | const metrics::gauge::time_point& timestamp 44 | ); 45 | 46 | event_message* create_set_event( 47 | std::string&& gauge_name, 48 | const metrics::gauge::value_type& value, 49 | const metrics::gauge::time_point& timestamp 50 | ); 51 | 52 | 53 | /* 54 | * Event destructor 55 | */ 56 | void delete_event(event_message* message); 57 | 58 | 59 | /* 60 | * Event processing function 61 | */ 62 | void process_event(metrics::gauge& counter, const event_message& message); 63 | 64 | }}} // namespace handystats::events::gauge 65 | 66 | 67 | #endif // HANDYSTATS_GAUGE_EVENT_HPP_ 68 | 69 | -------------------------------------------------------------------------------- /src/events/timer_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_TIMER_EVENT_HPP_ 19 | #define HANDYSTATS_TIMER_EVENT_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include "events/event_message_impl.hpp" 26 | 27 | 28 | namespace handystats { namespace events { namespace timer { 29 | 30 | namespace event_type { 31 | enum : char { 32 | INIT = 0, 33 | START, 34 | STOP, 35 | DISCARD, 36 | HEARTBEAT, 37 | SET 38 | }; 39 | } // namespace event_type 40 | 41 | /* 42 | * Event creation functions 43 | */ 44 | event_message* create_init_event( 45 | std::string&& timer_name, 46 | const metrics::timer::instance_id_type& instance_id, 47 | const metrics::timer::time_point& timestamp 48 | ); 49 | 50 | event_message* create_start_event( 51 | std::string&& timer_name, 52 | const metrics::timer::instance_id_type& instance_id, 53 | const metrics::timer::time_point& timestamp 54 | ); 55 | 56 | event_message* create_stop_event( 57 | std::string&& timer_name, 58 | const metrics::timer::instance_id_type& instance_id, 59 | const metrics::timer::time_point& timestamp 60 | ); 61 | 62 | event_message* create_discard_event( 63 | std::string&& timer_name, 64 | const metrics::timer::instance_id_type& instance_id, 65 | const metrics::timer::time_point& timestamp 66 | ); 67 | 68 | event_message* create_heartbeat_event( 69 | std::string&& timer_name, 70 | const metrics::timer::instance_id_type& instance_id, 71 | const metrics::timer::time_point& timestamp 72 | ); 73 | 74 | event_message* create_set_event( 75 | std::string&& timer_name, 76 | const metrics::timer::value_type& measurement, 77 | const metrics::timer::time_point& timestamp 78 | ); 79 | 80 | /* 81 | * Event destructor 82 | */ 83 | void delete_event(event_message* message); 84 | 85 | 86 | /* 87 | * Event processing function 88 | */ 89 | void process_event(metrics::timer& timer, const event_message& message); 90 | 91 | }}} // namespace handystats::events::timer 92 | 93 | 94 | #endif // HANDYSTATS_TIMER_EVENT_HPP_ 95 | -------------------------------------------------------------------------------- /src/internal_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_INTERNAL_IMPL_HPP_ 19 | #define HANDYSTATS_INTERNAL_IMPL_HPP_ 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | 28 | namespace handystats { namespace events { 29 | 30 | struct event_message; 31 | 32 | }} // namespace handystats::events 33 | 34 | 35 | namespace handystats { namespace internal { 36 | 37 | extern std::map metrics_map; 38 | 39 | void update_metrics(const chrono::time_point&); 40 | 41 | void process_event_message(const events::event_message&); 42 | 43 | size_t size(); 44 | 45 | void initialize(); 46 | void finalize(); 47 | 48 | 49 | namespace stats { 50 | 51 | extern metrics::gauge size; 52 | extern metrics::gauge process_time; 53 | 54 | void update(const chrono::time_point&); 55 | 56 | void initialize(); 57 | void finalize(); 58 | 59 | } // namespace stats 60 | 61 | 62 | }} // namespace handystats::internal 63 | 64 | 65 | #endif // HANDYSTATS_INTERNAL_IMPL_HPP_ 66 | -------------------------------------------------------------------------------- /src/json/attribute_json_writer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_ATTRIBUTE_JSON_WRITER_HPP_ 19 | #define HANDYSTATS_ATTRIBUTE_JSON_WRITER_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | #include "json/timestamp.hpp" 32 | 33 | namespace handystats { namespace json { 34 | 35 | template 36 | inline void write_to_json_value(const metrics::attribute* const obj, rapidjson::Value* json_value, Allocator& allocator) { 37 | if (!obj) { 38 | json_value = new rapidjson::Value(); 39 | return; 40 | } 41 | 42 | if (!json_value) { 43 | json_value = new rapidjson::Value(rapidjson::kObjectType); 44 | } 45 | else { 46 | json_value->SetObject(); 47 | } 48 | 49 | json_value->AddMember("type", "attribute", allocator); 50 | 51 | switch (obj->value().which()) { 52 | case metrics::attribute::value_index::BOOL: 53 | json_value->AddMember("value", boost::get(obj->value()), allocator); 54 | break; 55 | case metrics::attribute::value_index::INT: 56 | json_value->AddMember("value", boost::get(obj->value()), allocator); 57 | break; 58 | case metrics::attribute::value_index::UINT: 59 | json_value->AddMember("value", boost::get(obj->value()), allocator); 60 | break; 61 | case metrics::attribute::value_index::INT64: 62 | json_value->AddMember("value", boost::get(obj->value()), allocator); 63 | break; 64 | case metrics::attribute::value_index::UINT64: 65 | json_value->AddMember("value", boost::get(obj->value()), allocator); 66 | break; 67 | case metrics::attribute::value_index::DOUBLE: 68 | json_value->AddMember("value", boost::get(obj->value()), allocator); 69 | break; 70 | case metrics::attribute::value_index::STRING: 71 | json_value->AddMember("value", 72 | rapidjson::Value(boost::get(obj->value()).c_str(), allocator), 73 | allocator); 74 | break; 75 | } 76 | } 77 | 78 | template 79 | inline void write_to_json_buffer(const metrics::attribute* const obj, StringBuffer* buffer, Allocator& allocator) { 80 | rapidjson::Value json_value; 81 | write_to_json_value(obj, &json_value, allocator); 82 | 83 | if (!buffer) { 84 | buffer = new StringBuffer(); 85 | } 86 | 87 | rapidjson::PrettyWriter writer(*buffer); 88 | json_value.Accept(writer); 89 | } 90 | 91 | template 92 | inline std::string write_to_json_string(const metrics::attribute* const obj, Allocator&& allocator = Allocator()) { 93 | rapidjson::GenericStringBuffer, Allocator> buffer(&allocator); 94 | write_to_json_buffer(obj, &buffer, allocator); 95 | 96 | return std::string(buffer.GetString(), buffer.GetSize()); 97 | } 98 | 99 | }} // namespace handystats::json 100 | 101 | #endif // HANDYSTATS_ATTRIBUTE_JSON_WRITER_HPP_ 102 | -------------------------------------------------------------------------------- /src/json/counter_json_writer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_COUNTER_JSON_WRITER_HPP_ 19 | #define HANDYSTATS_COUNTER_JSON_WRITER_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include "json/gauge_json_writer.hpp" 30 | 31 | namespace handystats { namespace json { 32 | 33 | template 34 | inline void write_to_json_value(const metrics::counter* const obj, rapidjson::Value* json_value, Allocator& allocator) { 35 | if (!obj) { 36 | json_value = new rapidjson::Value(); 37 | return; 38 | } 39 | 40 | if (!json_value) { 41 | json_value = new rapidjson::Value(rapidjson::kObjectType); 42 | } 43 | else { 44 | json_value->SetObject(); 45 | } 46 | 47 | json_value->AddMember("type", "counter", allocator); 48 | 49 | write_to_json_value(&obj->values(), json_value, allocator); 50 | } 51 | 52 | template 53 | inline void write_to_json_buffer(const metrics::counter* const obj, StringBuffer* buffer, Allocator& allocator) { 54 | rapidjson::Value json_value; 55 | write_to_json_value(obj, &json_value, allocator); 56 | 57 | if (!buffer) { 58 | buffer = new StringBuffer(); 59 | } 60 | 61 | rapidjson::PrettyWriter writer(*buffer); 62 | json_value.Accept(writer); 63 | } 64 | 65 | template 66 | inline std::string write_to_json_string(const metrics::counter* const obj, Allocator&& allocator = Allocator()) { 67 | rapidjson::GenericStringBuffer, Allocator> buffer(&allocator); 68 | write_to_json_buffer(obj, &buffer, allocator); 69 | 70 | return std::string(buffer.GetString(), buffer.GetSize()); 71 | } 72 | 73 | }} // namespace handystats::json 74 | 75 | #endif // HANDYSTATS_COUNTER_JSON_WRITER_HPP_ 76 | -------------------------------------------------------------------------------- /src/json/gauge_json_writer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_GAUGE_JSON_WRITER_HPP_ 19 | #define HANDYSTATS_GAUGE_JSON_WRITER_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include "json/statistics_json_writer.hpp" 30 | 31 | namespace handystats { namespace json { 32 | 33 | template 34 | inline void write_to_json_value(const metrics::gauge* const obj, rapidjson::Value* json_value, Allocator& allocator) { 35 | if (!obj) { 36 | json_value = new rapidjson::Value(); 37 | return; 38 | } 39 | 40 | if (!json_value) { 41 | json_value = new rapidjson::Value(rapidjson::kObjectType); 42 | } 43 | else { 44 | json_value->SetObject(); 45 | } 46 | 47 | json_value->AddMember("type", "gauge", allocator); 48 | 49 | write_to_json_value(&obj->values(), json_value, allocator); 50 | } 51 | 52 | template 53 | inline void write_to_json_buffer(const metrics::gauge* const obj, StringBuffer* buffer, Allocator& allocator) { 54 | rapidjson::Value json_value; 55 | write_to_json_value(obj, &json_value, allocator); 56 | 57 | if (!buffer) { 58 | buffer = new StringBuffer(); 59 | } 60 | 61 | rapidjson::PrettyWriter writer(*buffer); 62 | json_value.Accept(writer); 63 | } 64 | 65 | template 66 | inline std::string write_to_json_string(const metrics::gauge* const obj, Allocator&& allocator = Allocator()) { 67 | rapidjson::GenericStringBuffer, Allocator> buffer(&allocator); 68 | write_to_json_buffer(obj, &buffer, allocator); 69 | 70 | return std::string(buffer.GetString(), buffer.GetSize()); 71 | } 72 | 73 | }} // namespace handystats::json 74 | 75 | #endif // HANDYSTATS_GAUGE_JSON_WRITER_HPP_ 76 | -------------------------------------------------------------------------------- /src/json/timer_json_writer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_TIMER_JSON_WRITER_HPP_ 19 | #define HANDYSTATS_TIMER_JSON_WRITER_HPP_ 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include "json/statistics_json_writer.hpp" 30 | 31 | namespace handystats { namespace json { 32 | 33 | template 34 | inline void write_to_json_value(const metrics::timer* const obj, rapidjson::Value* json_value, Allocator& allocator) { 35 | if (!obj) { 36 | json_value = new rapidjson::Value(); 37 | return; 38 | } 39 | 40 | if (!json_value) { 41 | json_value = new rapidjson::Value(rapidjson::kObjectType); 42 | } 43 | else { 44 | json_value->SetObject(); 45 | } 46 | 47 | json_value->AddMember("type", "timer", allocator); 48 | 49 | write_to_json_value(&obj->values(), json_value, allocator); 50 | } 51 | 52 | template 53 | inline void write_to_json_buffer(const metrics::timer* const obj, StringBuffer* buffer, Allocator& allocator) { 54 | rapidjson::Value json_value; 55 | write_to_json_value(obj, &json_value, allocator); 56 | 57 | if (!buffer) { 58 | buffer = new StringBuffer(); 59 | } 60 | 61 | rapidjson::PrettyWriter writer(*buffer); 62 | json_value.Accept(writer); 63 | } 64 | 65 | template 66 | inline std::string write_to_json_string(const metrics::timer* const obj, Allocator&& allocator = Allocator()) { 67 | rapidjson::GenericStringBuffer, Allocator> buffer(&allocator); 68 | write_to_json_buffer(obj, &buffer, allocator); 69 | 70 | return std::string(buffer.GetString(), buffer.GetSize()); 71 | } 72 | 73 | }} // namespace handystats::json 74 | 75 | #endif // HANDYSTATS_TIMER_JSON_WRITER_HPP_ 76 | -------------------------------------------------------------------------------- /src/json/timestamp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_JSON_TIMESTAMP_HPP_ 19 | #define HANDYSTATS_JSON_TIMESTAMP_HPP_ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | namespace handystats { namespace json { 27 | 28 | inline void write_to_json_value(const chrono::time_point& timestamp, rapidjson::Value* json_value) { 29 | if (!json_value) { 30 | json_value = new rapidjson::Value(); 31 | } 32 | 33 | chrono::time_point system_timestamp = chrono::time_point::convert_to(chrono::clock_type::SYSTEM, timestamp); 34 | 35 | json_value->SetUint64(chrono::duration::convert_to(chrono::time_unit::MSEC, system_timestamp.time_since_epoch()).count()); 36 | } 37 | 38 | template 39 | inline void write_to_json_buffer(const chrono::time_point& timestamp, StringBuffer* buffer, Allocator& allocator) { 40 | rapidjson::Value json_value; 41 | write_to_json_value(timestamp, &json_value, allocator); 42 | 43 | if (!buffer) { 44 | buffer = new StringBuffer(); 45 | } 46 | 47 | rapidjson::PrettyWriter writer(*buffer); 48 | json_value.Accept(writer); 49 | } 50 | 51 | template 52 | inline std::string write_to_json_string(const chrono::time_point& timestamp, Allocator&& allocator = Allocator()) { 53 | rapidjson::GenericStringBuffer, Allocator> buffer(&allocator); 54 | write_to_json_buffer(timestamp, &buffer, allocator); 55 | 56 | return std::string(buffer.GetString(), buffer.GetSize()); 57 | } 58 | }} // namespace handystats::json 59 | 60 | #endif // HANDYSTATS_JSON_TIMESTAMP_HPP_ 61 | -------------------------------------------------------------------------------- /src/json_dump.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | #include "json/gauge_json_writer.hpp" 21 | #include "json/counter_json_writer.hpp" 22 | #include "json/timer_json_writer.hpp" 23 | #include "json/attribute_json_writer.hpp" 24 | 25 | namespace handystats { namespace json { 26 | 27 | template 28 | void fill( 29 | rapidjson::Value& dump, Allocator& allocator, 30 | const std::map& metrics_map 31 | ) 32 | { 33 | dump.SetObject(); 34 | 35 | for (auto metric_iter = metrics_map.cbegin(); metric_iter != metrics_map.cend(); ++metric_iter) { 36 | rapidjson::Value metric_value; 37 | switch (metric_iter->second.which()) { 38 | case metrics::metric_index::GAUGE: 39 | json::write_to_json_value(&boost::get(metric_iter->second), &metric_value, allocator); 40 | break; 41 | case metrics::metric_index::COUNTER: 42 | json::write_to_json_value(&boost::get(metric_iter->second), &metric_value, allocator); 43 | break; 44 | case metrics::metric_index::TIMER: 45 | json::write_to_json_value(&boost::get(metric_iter->second), &metric_value, allocator); 46 | break; 47 | case metrics::metric_index::ATTRIBUTE: 48 | json::write_to_json_value(&boost::get(metric_iter->second), &metric_value, allocator); 49 | break; 50 | } 51 | 52 | dump.AddMember(rapidjson::Value(metric_iter->first.c_str(), allocator), 53 | rapidjson::Value(metric_value, allocator), 54 | allocator); 55 | } 56 | } 57 | 58 | std::string to_string(const std::map& metrics_map) { 59 | typedef rapidjson::MemoryPoolAllocator<> allocator_type; 60 | 61 | rapidjson::Value dump; 62 | allocator_type allocator; 63 | fill(dump, allocator, metrics_map); 64 | 65 | rapidjson::GenericStringBuffer, allocator_type> buffer(&allocator); 66 | rapidjson::PrettyWriter, allocator_type>> writer(buffer); 67 | dump.Accept(writer); 68 | 69 | return std::string(buffer.GetString(), buffer.GetSize()); 70 | } 71 | 72 | }} // namespace handystats::json 73 | 74 | std::string HANDY_JSON_DUMP() { 75 | return handystats::json::to_string(*HANDY_METRICS_DUMP()); 76 | } 77 | 78 | -------------------------------------------------------------------------------- /src/measuring_points/counter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "events/counter_impl.hpp" 22 | #include "message_queue_impl.hpp" 23 | #include "core_impl.hpp" 24 | 25 | #include 26 | #include 27 | 28 | 29 | namespace handystats { namespace measuring_points { 30 | 31 | void counter_init( 32 | std::string&& counter_name, 33 | const handystats::metrics::counter::value_type& init_value, 34 | const handystats::metrics::counter::time_point& timestamp 35 | ) 36 | { 37 | if (handystats::is_enabled()) { 38 | handystats::message_queue::push( 39 | handystats::events::counter::create_init_event(std::move(counter_name), init_value, timestamp) 40 | ); 41 | } 42 | } 43 | 44 | void counter_increment( 45 | std::string&& counter_name, 46 | const handystats::metrics::counter::value_type& value, 47 | const handystats::metrics::counter::time_point& timestamp 48 | ) 49 | { 50 | if (handystats::is_enabled()) { 51 | handystats::message_queue::push( 52 | handystats::events::counter::create_increment_event(std::move(counter_name), value, timestamp) 53 | ); 54 | } 55 | } 56 | 57 | void counter_decrement( 58 | std::string&& counter_name, 59 | const handystats::metrics::counter::value_type& value, 60 | const handystats::metrics::counter::time_point& timestamp 61 | ) 62 | { 63 | if (handystats::is_enabled()) { 64 | handystats::message_queue::push( 65 | handystats::events::counter::create_decrement_event(std::move(counter_name), value, timestamp) 66 | ); 67 | } 68 | } 69 | 70 | void counter_change( 71 | std::string&& counter_name, 72 | const handystats::metrics::counter::value_type& value, 73 | const handystats::metrics::counter::time_point& timestamp 74 | ) 75 | { 76 | if (handystats::is_enabled()) { 77 | if (value >= 0) { 78 | HANDY_COUNTER_INCREMENT(std::move(counter_name), value, timestamp); 79 | } 80 | else { 81 | HANDY_COUNTER_DECREMENT(std::move(counter_name), -value, timestamp); 82 | } 83 | } 84 | } 85 | 86 | }} // namespace handystats::measuring_points 87 | 88 | 89 | extern "C" { 90 | 91 | void handystats_counter_init( 92 | const char* counter_name, 93 | const int64_t init_value 94 | ) 95 | { 96 | handystats::measuring_points::counter_init(counter_name, init_value); 97 | } 98 | 99 | void handystats_counter_increment( 100 | const char* counter_name, 101 | const int64_t value 102 | ) 103 | { 104 | handystats::measuring_points::counter_increment(counter_name, value); 105 | } 106 | 107 | void handystats_counter_decrement( 108 | const char* counter_name, 109 | const int64_t value 110 | ) 111 | { 112 | handystats::measuring_points::counter_decrement(counter_name, value); 113 | } 114 | 115 | void handystats_counter_change( 116 | const char* counter_name, 117 | const int64_t value 118 | ) 119 | { 120 | handystats::measuring_points::counter_change(counter_name, value); 121 | } 122 | 123 | } // extern "C" 124 | -------------------------------------------------------------------------------- /src/measuring_points/gauge.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "events/gauge_impl.hpp" 22 | #include "message_queue_impl.hpp" 23 | #include "core_impl.hpp" 24 | 25 | #include 26 | #include 27 | 28 | 29 | namespace handystats { namespace measuring_points { 30 | 31 | void gauge_init( 32 | std::string&& gauge_name, 33 | const handystats::metrics::gauge::value_type& init_value, 34 | const handystats::metrics::gauge::time_point& timestamp 35 | ) 36 | { 37 | if (handystats::is_enabled()) { 38 | handystats::message_queue::push( 39 | handystats::events::gauge::create_init_event(std::move(gauge_name), init_value, timestamp) 40 | ); 41 | } 42 | } 43 | 44 | void gauge_set( 45 | std::string&& gauge_name, 46 | const handystats::metrics::gauge::value_type& value, 47 | const handystats::metrics::gauge::time_point& timestamp 48 | ) 49 | { 50 | if (handystats::is_enabled()) { 51 | handystats::message_queue::push( 52 | handystats::events::gauge::create_set_event(std::move(gauge_name), value, timestamp) 53 | ); 54 | } 55 | } 56 | 57 | }} // namespace handystats::measuring_points 58 | 59 | 60 | extern "C" { 61 | 62 | void handystats_gauge_init( 63 | const char* gauge_name, 64 | const double init_value 65 | ) 66 | { 67 | handystats::measuring_points::gauge_init(gauge_name, init_value); 68 | } 69 | 70 | void handystats_gauge_set( 71 | const char* gauge_name, 72 | const double value 73 | ) 74 | { 75 | handystats::measuring_points::gauge_set(gauge_name, value); 76 | } 77 | 78 | } // extern "C" 79 | -------------------------------------------------------------------------------- /src/measuring_points/timer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "events/timer_impl.hpp" 22 | #include "message_queue_impl.hpp" 23 | #include "core_impl.hpp" 24 | 25 | #include 26 | #include 27 | 28 | 29 | namespace handystats { namespace measuring_points { 30 | 31 | void timer_init( 32 | std::string&& timer_name, 33 | const metrics::timer::instance_id_type& instance_id, 34 | const metrics::timer::time_point& timestamp 35 | ) 36 | { 37 | if (is_enabled()) { 38 | message_queue::push( 39 | events::timer::create_init_event(std::move(timer_name), instance_id, timestamp) 40 | ); 41 | } 42 | } 43 | 44 | void timer_start( 45 | std::string&& timer_name, 46 | const metrics::timer::instance_id_type& instance_id, 47 | const metrics::timer::time_point& timestamp 48 | ) 49 | { 50 | if (is_enabled()) { 51 | message_queue::push( 52 | events::timer::create_start_event(std::move(timer_name), instance_id, timestamp) 53 | ); 54 | } 55 | } 56 | 57 | void timer_stop( 58 | std::string&& timer_name, 59 | const metrics::timer::instance_id_type& instance_id, 60 | const metrics::timer::time_point& timestamp 61 | ) 62 | { 63 | if (is_enabled()) { 64 | message_queue::push( 65 | events::timer::create_stop_event(std::move(timer_name), instance_id, timestamp) 66 | ); 67 | } 68 | } 69 | 70 | void timer_discard( 71 | std::string&& timer_name, 72 | const metrics::timer::instance_id_type& instance_id, 73 | const metrics::timer::time_point& timestamp 74 | ) 75 | { 76 | if (is_enabled()) { 77 | message_queue::push( 78 | events::timer::create_discard_event(std::move(timer_name), instance_id, timestamp) 79 | ); 80 | } 81 | } 82 | 83 | void timer_heartbeat( 84 | std::string&& timer_name, 85 | const metrics::timer::instance_id_type& instance_id, 86 | const metrics::timer::time_point& timestamp 87 | ) 88 | { 89 | if (is_enabled()) { 90 | message_queue::push( 91 | events::timer::create_heartbeat_event(std::move(timer_name), instance_id, timestamp) 92 | ); 93 | } 94 | } 95 | 96 | void timer_set( 97 | std::string&& timer_name, 98 | const metrics::timer::value_type& measurement, 99 | const metrics::timer::time_point& timestamp 100 | ) 101 | { 102 | if (is_enabled()) { 103 | message_queue::push( 104 | events::timer::create_set_event(std::move(timer_name), measurement, timestamp) 105 | ); 106 | } 107 | } 108 | 109 | }} // namespace measuring_points 110 | 111 | namespace { 112 | 113 | handystats::chrono::time_unit tsc_clock_unit; 114 | 115 | __attribute__((constructor(300))) 116 | void init_tsc_clock_unit() { 117 | tsc_clock_unit = handystats::chrono::tsc_clock::now().time_since_epoch().unit(); 118 | } 119 | 120 | } // unnamed namespace 121 | 122 | extern "C" { 123 | 124 | void handystats_timer_init( 125 | const char* timer_name, 126 | const uint64_t instance_id 127 | ) 128 | { 129 | handystats::measuring_points::timer_init(timer_name, instance_id); 130 | } 131 | 132 | void handystats_timer_start( 133 | const char* timer_name, 134 | const uint64_t instance_id 135 | ) 136 | { 137 | handystats::measuring_points::timer_start(timer_name, instance_id); 138 | } 139 | 140 | void handystats_timer_stop( 141 | const char* timer_name, 142 | const uint64_t instance_id 143 | ) 144 | { 145 | handystats::measuring_points::timer_stop(timer_name, instance_id); 146 | } 147 | 148 | void handystats_timer_discard( 149 | const char* timer_name, 150 | const uint64_t instance_id 151 | ) 152 | { 153 | handystats::measuring_points::timer_discard(timer_name, instance_id); 154 | } 155 | 156 | void handystats_timer_heartbeat( 157 | const char* timer_name, 158 | const uint64_t instance_id 159 | ) 160 | { 161 | handystats::measuring_points::timer_heartbeat(timer_name, instance_id); 162 | } 163 | 164 | void handystats_timer_set( 165 | const char* timer_name, 166 | const int64_t measurement 167 | ) 168 | { 169 | handystats::measuring_points::timer_set( 170 | timer_name, 171 | handystats::chrono::duration(measurement, tsc_clock_unit) 172 | ); 173 | } 174 | 175 | } // extern "C" 176 | -------------------------------------------------------------------------------- /src/message_queue_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_MESSAGE_QUEUE_IMPL_HPP_ 19 | #define HANDYSTATS_MESSAGE_QUEUE_IMPL_HPP_ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | namespace handystats { namespace events { 27 | 28 | struct event_message; 29 | 30 | }} // namespace handystats::events 31 | 32 | namespace handystats { namespace message_queue { 33 | 34 | struct node { 35 | std::atomic next; 36 | }; 37 | 38 | void push(node*); 39 | events::event_message* pop(); 40 | 41 | bool empty(); 42 | size_t size(); 43 | 44 | void initialize(); 45 | void finalize(); 46 | 47 | 48 | namespace stats { 49 | 50 | extern metrics::gauge size; 51 | extern metrics::gauge message_wait_time; 52 | extern metrics::counter pop_count; 53 | 54 | void update(const chrono::time_point&); 55 | 56 | void initialize(); 57 | void finalize(); 58 | 59 | } // namespace stats 60 | 61 | 62 | }} // namespace handystats::message_queue 63 | 64 | 65 | #endif // HANDYSTATS_MESSAGE_QUEUE_IMPL_HPP_ 66 | -------------------------------------------------------------------------------- /src/metrics/attribute.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | 21 | namespace handystats { namespace metrics { 22 | 23 | attribute::attribute() 24 | : m_value() 25 | { 26 | } 27 | 28 | void attribute::set(const attribute::value_type& value) { 29 | m_value = value; 30 | } 31 | 32 | void attribute::set(const bool& b) { 33 | m_value = b; 34 | } 35 | 36 | void attribute::set(const int& i) { 37 | m_value = i; 38 | } 39 | 40 | void attribute::set(const unsigned& u) { 41 | m_value = u; 42 | } 43 | 44 | void attribute::set(const int64_t& i64) { 45 | m_value = i64; 46 | } 47 | 48 | void attribute::set(const uint64_t& u64) { 49 | m_value = u64; 50 | } 51 | 52 | void attribute::set(const double& d) { 53 | m_value = d; 54 | } 55 | 56 | void attribute::set(const char* s) { 57 | set(std::string(s)); 58 | } 59 | 60 | void attribute::set(const std::string& s) { 61 | m_value = s; 62 | } 63 | 64 | const attribute::value_type& attribute::value() const { 65 | return m_value; 66 | } 67 | 68 | }} // namespace handystats::metrics 69 | -------------------------------------------------------------------------------- /src/metrics/counter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | 21 | namespace handystats { namespace metrics { 22 | 23 | counter::counter(const config::metrics::counter& opts) 24 | : m_values(opts.values) 25 | , m_value() 26 | , m_timestamp() 27 | { 28 | } 29 | 30 | 31 | void counter::init(const value_type& init_value, const time_point& timestamp) { 32 | m_value = init_value; 33 | m_timestamp = timestamp; 34 | 35 | m_values.reset(); 36 | 37 | m_values.update(m_value, m_timestamp); 38 | } 39 | 40 | void counter::increment(const value_type& incr_value, const time_point& timestamp) { 41 | if (m_timestamp == time_point()) { 42 | init(0, timestamp); 43 | } 44 | 45 | m_value += incr_value; 46 | if (m_timestamp < timestamp) { 47 | m_timestamp = timestamp; 48 | } 49 | 50 | m_values.update(m_value, m_timestamp); 51 | } 52 | 53 | void counter::decrement(const value_type& decr_value, const time_point& timestamp) { 54 | if (m_timestamp == time_point()) { 55 | init(0, timestamp); 56 | } 57 | 58 | m_value -= decr_value; 59 | if (m_timestamp < timestamp) { 60 | m_timestamp = timestamp; 61 | } 62 | 63 | m_values.update(m_value, m_timestamp); 64 | } 65 | 66 | void counter::update_statistics(const time_point& timestamp) { 67 | m_values.update_time(timestamp); 68 | } 69 | 70 | const statistics& counter::values() const { 71 | return m_values; 72 | } 73 | 74 | }} // namespace handystats::metrics 75 | -------------------------------------------------------------------------------- /src/metrics/gauge.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | namespace handystats { namespace metrics { 21 | 22 | gauge::gauge(const config::metrics::gauge& opts) 23 | : m_values(opts.values) 24 | { 25 | } 26 | 27 | void gauge::set(const value_type& value, const time_point& timestamp) { 28 | m_values.update(value, timestamp); 29 | } 30 | 31 | void gauge::update_statistics(const time_point& timestamp) { 32 | m_values.update_time(timestamp); 33 | } 34 | 35 | const statistics& gauge::values() const { 36 | return m_values; 37 | } 38 | 39 | }} // namespace handystats::metrics 40 | -------------------------------------------------------------------------------- /src/metrics/timer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | namespace handystats { namespace metrics { 21 | 22 | const timer::instance_id_type timer::DEFAULT_INSTANCE_ID = -1; 23 | const chrono::time_unit timer::value_unit = chrono::time_unit::USEC; 24 | 25 | timer::timer( 26 | const config::metrics::timer& timer_opts 27 | ) 28 | : m_idle_timeout(timer_opts.idle_timeout) 29 | , m_values(timer_opts.values) 30 | , m_idle_check_timestamp() 31 | { 32 | } 33 | 34 | void timer::start(const instance_id_type& instance_id, const time_point& timestamp) { 35 | check_idle_timeout(timestamp); 36 | 37 | auto& instance = m_instances[instance_id]; 38 | instance.start_timestamp = timestamp; 39 | instance.heartbeat_timestamp = timestamp; 40 | } 41 | 42 | void timer::stop(const instance_id_type& instance_id, const time_point& timestamp) { 43 | check_idle_timeout(timestamp); 44 | 45 | auto instance = m_instances.find(instance_id); 46 | if (instance == m_instances.end()) { 47 | return; 48 | } 49 | 50 | if (instance->second.expired(m_idle_timeout, timestamp)) { 51 | m_instances.erase(instance); 52 | return; 53 | } 54 | 55 | const auto& instance_value = 56 | chrono::duration::convert_to(value_unit, timestamp - instance->second.start_timestamp); 57 | 58 | m_values.update(instance_value.count(), timestamp); 59 | 60 | m_instances.erase(instance); 61 | } 62 | 63 | void timer::heartbeat(const instance_id_type& instance_id, const time_point& timestamp) { 64 | check_idle_timeout(timestamp); 65 | 66 | auto instance = m_instances.find(instance_id); 67 | if (instance == m_instances.end()) { 68 | return; 69 | } 70 | 71 | if (instance->second.expired(m_idle_timeout, timestamp)) { 72 | m_instances.erase(instance); 73 | return; 74 | } 75 | 76 | instance->second.heartbeat_timestamp = timestamp; 77 | } 78 | 79 | void timer::discard(const instance_id_type& instance_id, const time_point& timestamp) { 80 | check_idle_timeout(timestamp); 81 | 82 | m_instances.erase(instance_id); 83 | } 84 | 85 | void timer::set(const value_type& measurement, const time_point& timestamp) { 86 | m_values.update(chrono::duration::convert_to(value_unit, measurement).count(), timestamp); 87 | } 88 | 89 | void timer::check_idle_timeout(const time_point& timestamp, const bool& force) { 90 | if (!force) { 91 | if (timestamp < m_idle_check_timestamp + m_idle_timeout) { 92 | return; 93 | } 94 | } 95 | 96 | for (auto instance = m_instances.begin(); instance != m_instances.end();) { 97 | if (instance->second.expired(m_idle_timeout, timestamp)) { 98 | instance = m_instances.erase(instance); 99 | } 100 | else { 101 | ++instance; 102 | } 103 | } 104 | 105 | if (m_idle_check_timestamp < timestamp) { 106 | m_idle_check_timestamp = timestamp; 107 | } 108 | } 109 | 110 | void timer::update_statistics(const time_point& timestamp) { 111 | m_values.update_time(timestamp); 112 | } 113 | 114 | const statistics& timer::values() const { 115 | return m_values; 116 | } 117 | 118 | }} // namespace handystats::metrics 119 | -------------------------------------------------------------------------------- /src/metrics_dump_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_METRICS_DUMP_IMPL_HPP_ 19 | #define HANDYSTATS_METRICS_DUMP_IMPL_HPP_ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | namespace handystats { namespace metrics_dump { 30 | 31 | extern chrono::time_point dump_timestamp; 32 | 33 | void update(const chrono::time_point& system_time, const chrono::time_point& internal_time); 34 | 35 | const std::shared_ptr> get_dump(); 36 | 37 | void initialize(); 38 | void finalize(); 39 | 40 | 41 | namespace stats { 42 | 43 | extern metrics::gauge dump_time; 44 | 45 | void update(const chrono::time_point&); 46 | 47 | void initialize(); 48 | void finalize(); 49 | 50 | } // namespace stats 51 | 52 | 53 | }} // namespace handystats::metrics_dump 54 | 55 | #endif // HANDYSTATS_METRICS_DUMP_IMPL_HPP_ 56 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) YANDEX LLC. All rights reserved. 3 | # 4 | # This library is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU Lesser General Public 6 | # License as published by the Free Software Foundation; either 7 | # version 3.0 of the License, or (at your option) any later version. 8 | # 9 | # This library is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | # Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public 15 | # License along with this library. 16 | # 17 | 18 | CMAKE_MINIMUM_REQUIRED (VERSION 2.8) 19 | 20 | 21 | FIND_PACKAGE (Threads REQUIRED) 22 | INCLUDE_DIRECTORIES (${Threads_INCLUDE_DIR}) 23 | 24 | ADD_SUBDIRECTORY (${PROJECT_SOURCE_DIR}/thirdparty/googletest/googletest ${CMAKE_BINARY_DIR}/googletest) 25 | INCLUDE_DIRECTORIES (${gtest_SOURCE_DIR}/include) 26 | 27 | SET (GTEST_TARGETS gtest gtest_main) 28 | 29 | 30 | ADD_CUSTOM_TARGET (check COMMAND ${CMAKE_CTEST_COMMAND} -V) 31 | 32 | 33 | SET (TEST_LINK_FLAGS "-Wl,-rpath,${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_CURRENT_BINARY_DIR}/../${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") 34 | SET (TEST_PROPERTIES PROPERTIES LINK_FLAGS "${TEST_LINK_FLAGS}" LINKER_LANGUAGE CXX) 35 | SET (TEST_LIBRARIES gtest_main ${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT}) 36 | 37 | FILE (GLOB_RECURSE gtest_src_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.gtest.cpp") 38 | 39 | FOREACH (gtest_src_file IN LISTS gtest_src_files) 40 | STRING (REGEX REPLACE "[.]gtest[.]cpp$" "_gtest" gtest_exec_file ${gtest_src_file}) 41 | ADD_EXECUTABLE (${gtest_exec_file} EXCLUDE_FROM_ALL ${CMAKE_CURRENT_SOURCE_DIR}/${gtest_src_file}) 42 | SET_TARGET_PROPERTIES (${gtest_exec_file} ${TEST_PROPERTIES}) 43 | TARGET_LINK_LIBRARIES (${gtest_exec_file} ${TEST_LIBRARIES}) 44 | ADD_TEST (${gtest_exec_file} ${gtest_exec_file}) 45 | ADD_DEPENDENCIES (${gtest_exec_file} ${GTEST_TARGETS}) 46 | ADD_DEPENDENCIES (check ${gtest_exec_file}) 47 | ENDFOREACH (gtest_src_file) 48 | 49 | # C-Binging test 50 | SET (CBINDING_TEST_LINK_FLAGS "-Wl,-rpath,${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_CURRENT_BINARY_DIR}/../${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") 51 | SET (CBINDING_TEST_PROPERTIES_CXX PROPERTIES LINK_FLAGS "${CBINDING_TEST_LINK_FLAGS}" LINKER_LANGUAGE CXX) 52 | SET (CBINDING_TEST_PROPERTIES_C PROPERTIES LINK_FLAGS "${CBINDING_TEST_LINK_FLAGS}" LINKER_LANGUAGE C) 53 | SET (CBINDING_TEST_LIBRARIES gtest ${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT}) 54 | 55 | ADD_LIBRARY (cbinding_test STATIC EXCLUDE_FROM_ALL ${CMAKE_CURRENT_SOURCE_DIR}/c-binding/test.c) 56 | SET_TARGET_PROPERTIES (cbinding_test ${CBINDING_TEST_PROPERTIES_C}) 57 | TARGET_LINK_LIBRARIES (cbinding_test ${CBINDING_TEST_LIBRARIES}) 58 | 59 | ADD_EXECUTABLE (cbinding_check EXCLUDE_FROM_ALL ${CMAKE_CURRENT_SOURCE_DIR}/c-binding/check.cpp) 60 | SET_TARGET_PROPERTIES (cbinding_check ${CBINDING_TEST_PROPERTIES_CXX}) 61 | TARGET_LINK_LIBRARIES (cbinding_check ${CBINDING_TEST_LIBRARIES} cbinding_test) 62 | 63 | ADD_TEST(cbinding_check cbinding_check) 64 | ADD_DEPENDENCIES (cbinding_check ${GTEST_TARGETS} cbinding_test) 65 | ADD_DEPENDENCIES (check cbinding_check) 66 | -------------------------------------------------------------------------------- /tests/attribute.gtest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include "json/attribute_json_writer.hpp" 26 | 27 | using namespace handystats::metrics; 28 | 29 | TEST(AttributeTest, TestAttributeConstruction) { 30 | attribute sample_attr; 31 | const int value = -10; 32 | sample_attr.set(value); 33 | 34 | ASSERT_EQ(boost::get(sample_attr.value()), value); 35 | } 36 | 37 | TEST(AttributeTest, TestAttributeSetMethods) { 38 | attribute attr; 39 | 40 | { // bool 41 | const bool value = false; 42 | attr.set(value); 43 | ASSERT_EQ(boost::get(attr.value()), value); 44 | } 45 | { // double 46 | const double value = 1.25; 47 | attr.set(value); 48 | ASSERT_NEAR(boost::get(attr.value()), value, 1E-9); 49 | } 50 | { // int 51 | const int value = -123; 52 | attr.set(value); 53 | ASSERT_EQ(boost::get(attr.value()), value); 54 | } 55 | { // unsigned 56 | const unsigned value = 123; 57 | attr.set(value); 58 | ASSERT_EQ(boost::get(attr.value()), value); 59 | } 60 | { // int64_t 61 | const int64_t value = -1e18; 62 | attr.set(value); 63 | ASSERT_EQ(boost::get(attr.value()), value); 64 | } 65 | { // uint64_t 66 | const uint64_t value = 1e18; 67 | attr.set(value); 68 | ASSERT_EQ(boost::get(attr.value()), value); 69 | } 70 | { // string 71 | const std::string value = "test.string"; 72 | attr.set(value); 73 | ASSERT_EQ(boost::get(attr.value()), value); 74 | } 75 | { // char* 76 | const char* value = "test.const.char"; 77 | attr.set(value); 78 | ASSERT_EQ(boost::get(attr.value()), value); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /tests/c-binding/test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | #include "test.h" 24 | 25 | void run_test_gauge(void) { 26 | int gauge_value; 27 | for(gauge_value = TEST_GAUGE_MIN; gauge_value <= TEST_GAUGE_MAX; ++gauge_value) { 28 | HANDY_GAUGE_SET(("%s." TEST_GAUGE_NAME, "test"), gauge_value); 29 | } 30 | } 31 | 32 | void run_test_counter(void) { 33 | HANDY_COUNTER_INIT(("%s." TEST_COUNTER_NAME, "test"), TEST_COUNTER_INIT_VALUE); 34 | 35 | int incr_step; 36 | for (incr_step = 0; incr_step < TEST_COUNTER_INCR_COUNT; ++incr_step) { 37 | HANDY_COUNTER_INCREMENT(("%s." TEST_COUNTER_NAME, "test"), TEST_COUNTER_INCR_DELTA); 38 | } 39 | 40 | int decr_step; 41 | for (decr_step = 0; decr_step < TEST_COUNTER_DECR_COUNT; ++decr_step) { 42 | HANDY_COUNTER_DECREMENT(("%s." TEST_COUNTER_NAME, "test"), TEST_COUNTER_DECR_DELTA); 43 | } 44 | } 45 | 46 | void run_test_scoped_counter(void) { 47 | int cycle; 48 | for (cycle = 0; cycle < TEST_SCOPED_COUNTER_COUNT; ++cycle) { 49 | HANDY_COUNTER_SCOPE(("%s." TEST_SCOPED_COUNTER_NAME, "test"), TEST_SCOPED_COUNTER_DELTA); 50 | } 51 | } 52 | 53 | void run_test_timer(void) { 54 | struct timespec rqtp; 55 | rqtp.tv_sec = 0; 56 | rqtp.tv_nsec = TEST_TIMER_NANOSLEEP_TIME; 57 | 58 | int cycle; 59 | 60 | for (cycle = 0; cycle < TEST_TIMER_NANOSLEEP_COUNT; ++cycle) { 61 | HANDY_TIMER_START(("%s." TEST_TIMER_NAME, "test"), cycle); 62 | } 63 | 64 | nanosleep(&rqtp, NULL); 65 | 66 | for (cycle = 0; cycle < TEST_TIMER_NANOSLEEP_COUNT; ++cycle) { 67 | HANDY_TIMER_STOP(("%s." TEST_TIMER_NAME, "test"), cycle); 68 | } 69 | } 70 | 71 | void run_test_scoped_timer(void) { 72 | struct timespec rqtp; 73 | rqtp.tv_sec = 0; 74 | rqtp.tv_nsec = TEST_SCOPED_TIMER_NANOSLEEP_TIME; 75 | 76 | int cycle; 77 | 78 | for (cycle = 0; cycle < TEST_SCOPED_TIMER_NANOSLEEP_COUNT; ++cycle) { 79 | HANDY_TIMER_SCOPE(("%s." TEST_SCOPED_TIMER_NAME, "test")); 80 | nanosleep(&rqtp, NULL); 81 | } 82 | } 83 | 84 | void run_test_bool_attr(void) { 85 | HANDY_ATTRIBUTE_SET_BOOL(("%s." TEST_BOOL_ATTR_NAME, "test"), TEST_BOOL_ATTR_VALUE); 86 | } 87 | 88 | void run_test_double_attr(void) { 89 | HANDY_ATTRIBUTE_SET_DOUBLE(("%s." TEST_DOUBLE_ATTR_NAME, "test"), TEST_DOUBLE_ATTR_VALUE); 90 | } 91 | 92 | void run_test_int_attr(void) { 93 | HANDY_ATTRIBUTE_SET_INT(("%s." TEST_INT_ATTR_NAME, "test"), TEST_INT_ATTR_VALUE); 94 | } 95 | 96 | void run_test_uint_attr(void) { 97 | HANDY_ATTRIBUTE_SET_UINT(("%s." TEST_UINT_ATTR_NAME, "test"), TEST_UINT_ATTR_VALUE); 98 | } 99 | 100 | void run_test_int64_attr(void) { 101 | HANDY_ATTRIBUTE_SET_INT64(("%s." TEST_INT64_ATTR_NAME, "test"), TEST_INT64_ATTR_VALUE); 102 | } 103 | 104 | void run_test_uint64_attr(void) { 105 | HANDY_ATTRIBUTE_SET_UINT64(("%s." TEST_UINT64_ATTR_NAME, "test"), TEST_UINT64_ATTR_VALUE); 106 | } 107 | 108 | void run_test_string_attr(void) { 109 | HANDY_ATTRIBUTE_SET_STRING(("%s." TEST_STRING_ATTR_NAME, "test"), TEST_STRING_ATTR_VALUE); 110 | } 111 | 112 | void run_test_attr(void) { 113 | run_test_bool_attr(); 114 | run_test_double_attr(); 115 | run_test_int_attr(); 116 | run_test_uint_attr(); 117 | run_test_int64_attr(); 118 | run_test_uint64_attr(); 119 | run_test_string_attr(); 120 | } 121 | 122 | int main(int argc, char** argv) { 123 | HANDY_CONFIG_JSON("{\"metrics-dump\":{\"interval\": 20}}"); 124 | HANDY_INIT(); 125 | 126 | run_test_gauge(); 127 | run_test_counter(); 128 | run_test_scoped_counter(); 129 | run_test_timer(); 130 | run_test_scoped_timer(); 131 | run_test_attr(); 132 | 133 | int ret = check_tests(argc, argv); 134 | 135 | HANDY_FINALIZE(); 136 | 137 | return ret; 138 | } 139 | -------------------------------------------------------------------------------- /tests/c-binding/test.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #define TEST_GAUGE_NAME "gauge" 19 | #define TEST_GAUGE_MIN -10 20 | #define TEST_GAUGE_MAX 10 21 | 22 | #define TEST_COUNTER_NAME "counter" 23 | #define TEST_COUNTER_INIT_VALUE 0 24 | #define TEST_COUNTER_INCR_DELTA 3 25 | #define TEST_COUNTER_INCR_COUNT 10 26 | #define TEST_COUNTER_DECR_DELTA 3 27 | #define TEST_COUNTER_DECR_COUNT 15 28 | 29 | #define TEST_SCOPED_COUNTER_NAME "scoped.counter" 30 | #define TEST_SCOPED_COUNTER_DELTA 123 31 | #define TEST_SCOPED_COUNTER_COUNT 15 32 | 33 | #define TEST_TIMER_NAME "timer" 34 | #define TEST_TIMER_NANOSLEEP_TIME 10000 35 | #define TEST_TIMER_NANOSLEEP_COUNT 10 36 | 37 | #define TEST_SCOPED_TIMER_NAME "scoped.timer" 38 | #define TEST_SCOPED_TIMER_NANOSLEEP_TIME 20000 39 | #define TEST_SCOPED_TIMER_NANOSLEEP_COUNT 5 40 | 41 | #define TEST_BOOL_ATTR_NAME "bool.attr" 42 | #define TEST_BOOL_ATTR_VALUE 1 43 | 44 | #define TEST_DOUBLE_ATTR_NAME "double.attr" 45 | #define TEST_DOUBLE_ATTR_VALUE 12345678.9 46 | 47 | #define TEST_INT_ATTR_NAME "int.attr" 48 | #define TEST_INT_ATTR_VALUE -123456 49 | 50 | #define TEST_UINT_ATTR_NAME "uint.attr" 51 | #define TEST_UINT_ATTR_VALUE 123456789 52 | 53 | #define TEST_INT64_ATTR_NAME "int64.attr" 54 | #define TEST_INT64_ATTR_VALUE -1234567890 55 | 56 | #define TEST_UINT64_ATTR_NAME "uint64.attr" 57 | #define TEST_UINT64_ATTR_VALUE 1234567890 58 | 59 | #define TEST_STRING_ATTR_NAME "string.attr" 60 | #define TEST_STRING_ATTR_VALUE "test.string" 61 | 62 | #include 63 | 64 | HANDYSTATS_EXTERN_C int check_tests(int argc, char** argv); 65 | -------------------------------------------------------------------------------- /tests/counter.gtest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include "json/counter_json_writer.hpp" 26 | 27 | using namespace handystats::metrics; 28 | 29 | TEST(CounterTest, TestCounterConstruction) { 30 | counter sample_counter; 31 | sample_counter.init(10); 32 | 33 | ASSERT_EQ(sample_counter.values().get(), 10); 34 | } 35 | 36 | TEST(CounterTest, TestCounterIncrementDecrement) { 37 | counter sample_counter; 38 | 39 | const int min_test_value = 1E3; 40 | const int max_test_value = 1E4; 41 | 42 | sample_counter.increment(min_test_value); 43 | ASSERT_EQ(sample_counter.values().get(), min_test_value); 44 | 45 | for (int step = 0; step < max_test_value - min_test_value; ++step) { 46 | sample_counter.increment(1); 47 | } 48 | ASSERT_EQ(sample_counter.values().get(), max_test_value); 49 | 50 | for (int step = 0; step < max_test_value; ++step) { 51 | sample_counter.decrement(1); 52 | } 53 | ASSERT_EQ(sample_counter.values().get(), 0); 54 | } 55 | 56 | TEST(CounterTest, TestCounterInternalStats) { 57 | counter sample_counter; 58 | 59 | const int min_test_value = 1E3; 60 | const int max_test_value = 1E4; 61 | 62 | sample_counter.increment(min_test_value); 63 | sample_counter.increment(max_test_value - min_test_value); 64 | 65 | ASSERT_EQ(sample_counter.values().get(), 0); 66 | ASSERT_EQ(sample_counter.values().get(), max_test_value); 67 | 68 | for (int step = 0; step < max_test_value; ++step) { 69 | sample_counter.decrement(1); 70 | } 71 | 72 | ASSERT_EQ(sample_counter.values().get(), 0); 73 | ASSERT_EQ(sample_counter.values().get(), max_test_value); 74 | } 75 | -------------------------------------------------------------------------------- /tests/counter_events.gtest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | 22 | #include 23 | 24 | #include "events/event_message_impl.hpp" 25 | #include "events/counter_impl.hpp" 26 | 27 | 28 | using namespace handystats::events::counter; 29 | 30 | TEST(CounterEventsTest, TestCounterInitEvent) { 31 | const char* counter_name = "queue.size"; 32 | const handystats::metrics::counter::value_type init_value = 10; 33 | auto message = create_init_event(counter_name, init_value, handystats::metrics::counter::clock::now()); 34 | 35 | ASSERT_EQ(message->destination_name, counter_name); 36 | ASSERT_EQ(message->destination_type, handystats::events::event_destination_type::COUNTER); 37 | 38 | ASSERT_EQ(message->event_type, event_type::INIT); 39 | ASSERT_EQ(reinterpret_cast(message->event_data), init_value); 40 | 41 | delete_event_message(message); 42 | } 43 | 44 | TEST(CounterEventsTest, TestCounterIncrementEvent) { 45 | const char* counter_name = "queue.size"; 46 | const handystats::metrics::counter::value_type value = 2; 47 | auto message = create_increment_event(counter_name, value, handystats::metrics::counter::clock::now()); 48 | 49 | ASSERT_EQ(message->destination_name, counter_name); 50 | ASSERT_EQ(message->destination_type, handystats::events::event_destination_type::COUNTER); 51 | 52 | ASSERT_EQ(message->event_type, event_type::INCREMENT); 53 | ASSERT_EQ(reinterpret_cast(message->event_data), value); 54 | 55 | delete_event_message(message); 56 | } 57 | 58 | TEST(CounterEventsTest, TestCounterDecrementEvent) { 59 | const char* counter_name = "queue.size"; 60 | const handystats::metrics::counter::value_type value = -1; 61 | auto message = create_decrement_event(counter_name, value, handystats::metrics::counter::clock::now()); 62 | 63 | ASSERT_EQ(message->destination_name, counter_name); 64 | ASSERT_EQ(message->destination_type, handystats::events::event_destination_type::COUNTER); 65 | 66 | ASSERT_EQ(message->event_type, event_type::DECREMENT); 67 | ASSERT_EQ(reinterpret_cast(message->event_data), value); 68 | 69 | delete_event_message(message); 70 | } 71 | 72 | -------------------------------------------------------------------------------- /tests/event_message_queue.gtest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | 27 | #include "events/event_message_impl.hpp" 28 | #include "message_queue_impl.hpp" 29 | 30 | namespace handystats { 31 | 32 | extern std::atomic enabled_flag; 33 | 34 | } // namespace handystats 35 | 36 | class EventMessageQueueTest : public ::testing::Test { 37 | protected: 38 | virtual void SetUp() { 39 | handystats::message_queue::initialize(); 40 | handystats::enabled_flag.store(true, std::memory_order_release); 41 | } 42 | virtual void TearDown() { 43 | handystats::message_queue::finalize(); 44 | handystats::enabled_flag.store(false, std::memory_order_release); 45 | } 46 | }; 47 | 48 | 49 | TEST_F(EventMessageQueueTest, SinglePushCorrectlyAddsMessage) { 50 | HANDY_COUNTER_INIT("counter.name", 10); 51 | ASSERT_EQ(handystats::message_queue::size(), 1); 52 | 53 | HANDY_COUNTER_INCREMENT("counter.name", 1); 54 | ASSERT_EQ(handystats::message_queue::size(), 2); 55 | 56 | HANDY_COUNTER_DECREMENT("counter.name", 11); 57 | ASSERT_EQ(handystats::message_queue::size(), 3); 58 | 59 | HANDY_COUNTER_CHANGE("counter.name", -10); 60 | ASSERT_EQ(handystats::message_queue::size(), 4); 61 | } 62 | 63 | TEST_F(EventMessageQueueTest, MultiplePushesCorrectlyAddMessages) { 64 | HANDY_COUNTER_INIT("counter.name", 10); 65 | HANDY_COUNTER_INCREMENT("counter.name", 1); 66 | HANDY_COUNTER_DECREMENT("counter.name", 11); 67 | HANDY_COUNTER_CHANGE("counter.name", 13); 68 | 69 | ASSERT_EQ(handystats::message_queue::size(), 4); 70 | } 71 | 72 | TEST_F(EventMessageQueueTest, PushDifferentMessages) { 73 | HANDY_COUNTER_INIT("counter.name", 10); 74 | HANDY_GAUGE_INIT("gauge.name", 10); 75 | HANDY_TIMER_INIT("timer.name"); 76 | 77 | ASSERT_EQ(handystats::message_queue::size(), 3); 78 | } 79 | 80 | -------------------------------------------------------------------------------- /tests/gauge.gtest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include "json/gauge_json_writer.hpp" 26 | 27 | using namespace handystats::metrics; 28 | 29 | TEST(GaugeTest, TestGaugeConstruction) { 30 | gauge sample_gauge; 31 | sample_gauge.set(-10); 32 | 33 | ASSERT_NEAR(sample_gauge.values().get(), -10, 1E-9); 34 | } 35 | 36 | TEST(GaugeTest, TestGaugeSetMethod) { 37 | gauge sample_gauge; 38 | 39 | for (int test_value = -1E3; test_value < 1E3; ++test_value) { 40 | sample_gauge.set(test_value); 41 | 42 | ASSERT_NEAR(sample_gauge.values().get(), test_value, 1E-9); 43 | } 44 | } 45 | 46 | TEST(GaugeTest, TestGaugeInternalStats) { 47 | gauge sample_gauge; 48 | 49 | const int min_test_value = -1E3; 50 | const int max_test_value = 1E3; 51 | 52 | for (int test_value = min_test_value; test_value <= max_test_value; ++test_value) { 53 | sample_gauge.set(test_value); 54 | } 55 | 56 | 57 | const auto& stats = sample_gauge.values(); 58 | ASSERT_NEAR(stats.get(), min_test_value, 1E-9); 59 | ASSERT_NEAR(stats.get(), max_test_value, 1E-9); 60 | 61 | ASSERT_EQ(stats.get(), max_test_value - min_test_value + 1); 62 | ASSERT_NEAR(stats.get(), 0, 1E-9); 63 | ASSERT_NEAR(stats.get(), 0, 1E-9); 64 | } 65 | -------------------------------------------------------------------------------- /tests/gauge_events.gtest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | 22 | #include 23 | 24 | #include "events/event_message_impl.hpp" 25 | #include "events/gauge_impl.hpp" 26 | 27 | 28 | using namespace handystats::events::gauge; 29 | 30 | TEST(GaugeEventsTest, TestGaugeInitEvent) { 31 | const char* gauge_name = "proc.load"; 32 | const double init_value = 0.75; 33 | auto message = create_init_event(gauge_name, init_value, handystats::metrics::gauge::clock::now()); 34 | 35 | ASSERT_EQ(message->destination_name, gauge_name); 36 | ASSERT_EQ(message->destination_type, handystats::events::event_destination_type::GAUGE); 37 | 38 | ASSERT_EQ(message->event_type, event_type::INIT); 39 | ASSERT_NEAR(*reinterpret_cast(&message->event_data), init_value, 1E-6); 40 | 41 | delete_event_message(message); 42 | } 43 | 44 | TEST(GaugeEventsTest, TestGaugeSetEvent) { 45 | const char* gauge_name = "proc.load"; 46 | const double value = 1.5; 47 | auto message = create_set_event(gauge_name, value, handystats::metrics::gauge::clock::now()); 48 | 49 | ASSERT_EQ(message->destination_name, gauge_name); 50 | ASSERT_EQ(message->destination_type, handystats::events::event_destination_type::GAUGE); 51 | 52 | ASSERT_EQ(message->event_type, event_type::SET); 53 | ASSERT_NEAR(*reinterpret_cast(&message->event_data), value, 1E-6); 54 | 55 | delete_event_message(message); 56 | } 57 | 58 | -------------------------------------------------------------------------------- /tests/handy.gtest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #include "message_queue_helper.hpp" 35 | #include "metrics_dump_helper.hpp" 36 | 37 | class HandyCounterTest : public ::testing::Test { 38 | protected: 39 | virtual void SetUp() { 40 | HANDY_CONFIG_JSON( 41 | "{\ 42 | \"dump-interval\": 10\ 43 | }" 44 | ); 45 | 46 | HANDY_INIT(); 47 | } 48 | virtual void TearDown() { 49 | HANDY_FINALIZE(); 50 | } 51 | }; 52 | 53 | class HandyGaugeTest : public ::testing::Test { 54 | protected: 55 | virtual void SetUp() { 56 | HANDY_CONFIG_JSON( 57 | "{\ 58 | \"dump-interval\": 10\ 59 | }" 60 | ); 61 | 62 | HANDY_INIT(); 63 | } 64 | virtual void TearDown() { 65 | HANDY_FINALIZE(); 66 | } 67 | }; 68 | 69 | TEST_F(HandyCounterTest, HandyBubbleSortMonitoring) { 70 | const int SIZE = 50; 71 | std::vector data(SIZE); 72 | for (auto element = data.begin(); element != data.end(); ++element) { 73 | *element = rand(); 74 | } 75 | 76 | int swaps_count = 0; 77 | for (int step = 0; step < SIZE - 1; ++step) { 78 | bool sorted = true; 79 | for (int i = 0; i < SIZE - 1; ++i) { 80 | if (data[i] > data[i + 1]) { 81 | std::swap(data[i], data[i + 1]); 82 | sorted = false; 83 | swaps_count++; 84 | 85 | HANDY_COUNTER_INCREMENT("swaps.count", 1); 86 | } 87 | } 88 | 89 | if (sorted) { 90 | break; 91 | } 92 | } 93 | 94 | handystats::message_queue::wait_until_empty(); 95 | handystats::metrics_dump::wait_until(handystats::chrono::system_clock::now()); 96 | 97 | auto metrics_dump = HANDY_METRICS_DUMP(); 98 | 99 | ASSERT_TRUE(metrics_dump->find("swaps.count") != metrics_dump->end()); 100 | 101 | int handy_count = 102 | boost::get(metrics_dump->at("swaps.count")) 103 | .values() 104 | .get(); 105 | 106 | ASSERT_EQ(handy_count, swaps_count); 107 | } 108 | 109 | TEST_F(HandyGaugeTest, HandyQueueSizeMonitoring) { 110 | const int OPER_COUNT = 5000; 111 | std::queue data; 112 | 113 | int max_queue_size = 0; 114 | for (int oper = 0; oper < OPER_COUNT; ++oper) { 115 | if (rand() & 1) { 116 | data.push(rand()); 117 | } 118 | else { 119 | if (!data.empty()) { 120 | data.pop(); 121 | } 122 | } 123 | HANDY_GAUGE_SET("queue.size", data.size()); 124 | 125 | if (data.size() > max_queue_size) { 126 | max_queue_size = data.size(); 127 | } 128 | } 129 | 130 | handystats::message_queue::wait_until_empty(); 131 | handystats::metrics_dump::wait_until(handystats::chrono::system_clock::now()); 132 | 133 | auto metrics_dump = HANDY_METRICS_DUMP(); 134 | 135 | ASSERT_TRUE(metrics_dump->find("queue.size") != metrics_dump->end()); 136 | 137 | int handy_max_size = 138 | boost::get(metrics_dump->at("queue.size")) 139 | .values() 140 | .get(); 141 | 142 | ASSERT_EQ(handy_max_size, max_queue_size); 143 | } 144 | 145 | -------------------------------------------------------------------------------- /tests/json_dump.gtest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "message_queue_helper.hpp" 34 | #include "metrics_dump_helper.hpp" 35 | 36 | static void check_full_json_dump(const std::string& string_dump) { 37 | rapidjson::Document dump; 38 | dump.Parse<0>(string_dump.c_str()); 39 | 40 | for (rapidjson::Value::MemberIterator iter = dump.MemberBegin(); iter != dump.MemberEnd(); ++iter) { 41 | ASSERT_TRUE(iter->value.IsObject()); 42 | ASSERT_TRUE(iter->value.HasMember("type")); 43 | 44 | std::string type(iter->value.FindMember("type")->value.GetString(), iter->value.FindMember("type")->value.GetStringLength()); 45 | std::string name(iter->name.GetString()); 46 | 47 | // skip internal metrics 48 | if (name.find("handystats") == 0) { 49 | continue; 50 | } 51 | 52 | if (type == "gauge") { 53 | // ASSERT_TRUE(iter->value.HasMember("timestamp")); 54 | // ASSERT_TRUE(iter->value.HasMember("value")); 55 | 56 | // ASSERT_TRUE(iter->value.HasMember("values")); 57 | } 58 | else if (type == "counter") { 59 | // ASSERT_TRUE(iter->value.HasMember("timestamp")); 60 | // ASSERT_TRUE(iter->value.HasMember("value")); 61 | 62 | // ASSERT_TRUE(iter->value.HasMember("values")); 63 | } 64 | else if (type == "timer") { 65 | // ASSERT_TRUE(iter->value.HasMember("timestamp")); 66 | // ASSERT_TRUE(iter->value.HasMember("value")); 67 | 68 | // ASSERT_TRUE(iter->value.HasMember("values")); 69 | } 70 | else if (type == "attribute") { 71 | // ASSERT_TRUE(iter->value.HasMember("timestamp")); 72 | ASSERT_TRUE(iter->value.HasMember("value")); 73 | } 74 | } 75 | } 76 | 77 | TEST(JsonDumpTest, TestJsonDumpMethods) { 78 | HANDY_CONFIG_JSON( 79 | "{\ 80 | \"dump-interval\": 1\ 81 | }" 82 | ); 83 | 84 | HANDY_INIT(); 85 | 86 | for (int i = 0; i < 10; ++i) { 87 | HANDY_TIMER_START("test.timer"); 88 | HANDY_GAUGE_SET("test.gauge", i); 89 | HANDY_COUNTER_INCREMENT("test.counter", i); 90 | HANDY_ATTRIBUTE_SET("cycle.interation", i); 91 | HANDY_TIMER_STOP("test.timer"); 92 | } 93 | 94 | handystats::message_queue::wait_until_empty(); 95 | handystats::metrics_dump::wait_until(handystats::chrono::system_clock::now()); 96 | 97 | std::string string_dump = handystats::json::to_string(*HANDY_METRICS_DUMP()); 98 | 99 | check_full_json_dump(string_dump); 100 | 101 | check_full_json_dump(HANDY_JSON_DUMP()); 102 | 103 | HANDY_FINALIZE(); 104 | } 105 | 106 | TEST(JsonDumpTest, CheckEmptyStatisticsNotShown) { 107 | HANDY_CONFIG_JSON( 108 | "{\ 109 | \"gauge\": {\ 110 | \"tags\": []\ 111 | },\ 112 | \"counter\": {\ 113 | },\ 114 | \"dump-interval\": 1\ 115 | }" 116 | ); 117 | 118 | HANDY_INIT(); 119 | 120 | for (int i = 0; i < 10; ++i) { 121 | HANDY_TIMER_START("test.timer"); 122 | HANDY_GAUGE_SET("test.gauge", i); 123 | HANDY_COUNTER_INCREMENT("test.counter", i); 124 | HANDY_ATTRIBUTE_SET("cycle.interation", i); 125 | HANDY_TIMER_STOP("test.timer"); 126 | } 127 | 128 | handystats::message_queue::wait_until_empty(); 129 | handystats::metrics_dump::wait_until(handystats::chrono::system_clock::now()); 130 | 131 | auto metrics_dump = HANDY_METRICS_DUMP(); 132 | 133 | // rapidjson::Document dump; 134 | // handystats::json::fill(dump, dump.GetAllocator(), *metrics_dump); 135 | 136 | // ASSERT_FALSE(dump["test.gauge"].HasMember("values")); 137 | 138 | // ASSERT_TRUE(dump["test.counter"].HasMember("values")); 139 | 140 | // ASSERT_TRUE(dump["test.timer"].HasMember("values")); 141 | 142 | HANDY_FINALIZE(); 143 | } 144 | -------------------------------------------------------------------------------- /tests/math_utils.gtest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | 22 | TEST(MathUtils, TestIntComparison) { 23 | ASSERT_LT(handystats::math_utils::cmp(10, 11), 0); 24 | ASSERT_EQ(handystats::math_utils::cmp(1000, 1000), 0); 25 | ASSERT_GT(handystats::math_utils::cmp(10, -100), 0); 26 | } 27 | 28 | TEST(MathUtils, TestDoubleComparison) { 29 | ASSERT_LT(handystats::math_utils::cmp(100.0, 100.00001), 0); 30 | ASSERT_EQ(handystats::math_utils::cmp(101.0, 1111 / 11), 0); 31 | ASSERT_GT(handystats::math_utils::cmp(101.0, (1111 - 0.000011) / 11), 0); 32 | } 33 | 34 | TEST(MathUtils, TestSqrt) { 35 | ASSERT_DOUBLE_EQ(handystats::math_utils::sqrt(0), 0); 36 | 37 | const double value = 11.22334455; 38 | ASSERT_DOUBLE_EQ(handystats::math_utils::sqrt(value * value), value); 39 | 40 | const double sqrt_value = handystats::math_utils::sqrt(value); 41 | ASSERT_DOUBLE_EQ(sqrt_value * sqrt_value, value); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /tests/message_queue_helper.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_TESTS_MESSAGE_QUEUE_HELPER_HPP_ 19 | #define HANDYSTATS_TESTS_MESSAGE_QUEUE_HELPER_HPP_ 20 | 21 | #include 22 | #include 23 | 24 | #include "message_queue_impl.hpp" 25 | 26 | namespace handystats { namespace message_queue { 27 | 28 | void wait_until_empty() { 29 | while (!handystats::message_queue::empty()) { 30 | std::this_thread::sleep_for(std::chrono::microseconds(1)); 31 | } 32 | } 33 | 34 | }} // namespace handystats::message_queue 35 | 36 | #endif // HANDYSTATS_TESTS_MESSAGE_QUEUE_HELPER_HPP_ 37 | -------------------------------------------------------------------------------- /tests/metrics_dump.gtest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include "message_queue_helper.hpp" 36 | #include "metrics_dump_helper.hpp" 37 | 38 | class MetricsDumpTest : public ::testing::Test { 39 | protected: 40 | virtual void SetUp() { 41 | HANDY_CONFIG_JSON( 42 | "{\ 43 | \"dump-interval\": 10\ 44 | }" 45 | ); 46 | 47 | HANDY_INIT(); 48 | } 49 | virtual void TearDown() { 50 | HANDY_FINALIZE(); 51 | } 52 | }; 53 | 54 | TEST_F(MetricsDumpTest, SampleCounter) { 55 | const size_t INCR_COUNT = 100; 56 | const size_t INCR_VALUE = 10; 57 | 58 | for (size_t i = 0; i < INCR_COUNT; ++i) { 59 | HANDY_COUNTER_INCREMENT("counter", INCR_VALUE); 60 | } 61 | 62 | handystats::message_queue::wait_until_empty(); 63 | handystats::metrics_dump::wait_until(handystats::chrono::system_clock::now()); 64 | 65 | auto metrics_dump = HANDY_METRICS_DUMP(); 66 | 67 | ASSERT_TRUE(metrics_dump->find("counter") != metrics_dump->end()); 68 | 69 | auto& counter = boost::get(metrics_dump->at("counter")); 70 | ASSERT_EQ(counter.values().get(), INCR_COUNT * INCR_VALUE); 71 | } 72 | 73 | TEST_F(MetricsDumpTest, SampleTimer) { 74 | const std::chrono::milliseconds sleep_interval(10); 75 | const size_t TIMER_INSTANCES = 10; 76 | 77 | for (size_t i = 0; i < TIMER_INSTANCES; ++i) { 78 | HANDY_TIMER_START("timer", i); 79 | } 80 | 81 | std::this_thread::sleep_for(sleep_interval); 82 | 83 | for (size_t i = 0; i < TIMER_INSTANCES; ++i) { 84 | HANDY_TIMER_STOP("timer", i); 85 | } 86 | 87 | handystats::message_queue::wait_until_empty(); 88 | handystats::metrics_dump::wait_until(handystats::chrono::system_clock::now()); 89 | 90 | auto metrics_dump = HANDY_METRICS_DUMP(); 91 | 92 | ASSERT_TRUE(metrics_dump->find("timer") != metrics_dump->end()); 93 | 94 | auto& timer = boost::get(metrics_dump->at("timer")); 95 | ASSERT_EQ(timer.values().get(), TIMER_INSTANCES); 96 | ASSERT_TRUE( 97 | timer.values().get() >= 98 | handystats::chrono::duration::convert_to(handystats::metrics::timer::value_unit, 99 | handystats::chrono::duration(sleep_interval.count(), handystats::chrono::time_unit::MSEC)).count() 100 | ); 101 | } 102 | 103 | TEST_F(MetricsDumpTest, SampleGauge) { 104 | const size_t MIN_VALUE = 0; 105 | const size_t MAX_VALUE = 100; 106 | 107 | for (size_t value = MIN_VALUE; value <= MAX_VALUE; ++value) { 108 | HANDY_GAUGE_SET("gauge", value); 109 | } 110 | 111 | handystats::message_queue::wait_until_empty(); 112 | handystats::metrics_dump::wait_until(handystats::chrono::system_clock::now()); 113 | 114 | auto metrics_dump = HANDY_METRICS_DUMP(); 115 | 116 | ASSERT_TRUE(metrics_dump->find("gauge") != metrics_dump->end()); 117 | 118 | auto& gauge = boost::get(metrics_dump->at("gauge")); 119 | ASSERT_EQ(gauge.values().get(), MAX_VALUE - MIN_VALUE + 1); 120 | ASSERT_EQ(gauge.values().get(), MIN_VALUE); 121 | ASSERT_EQ(gauge.values().get(), MAX_VALUE); 122 | ASSERT_EQ(gauge.values().get(), (MAX_VALUE + MIN_VALUE) / 2.0); 123 | } 124 | -------------------------------------------------------------------------------- /tests/metrics_dump_helper.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #ifndef HANDYSTATS_TESTS_METRICS_DUMP_HELPER_HPP_ 19 | #define HANDYSTATS_TESTS_METRICS_DUMP_HELPER_HPP_ 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include "metrics_dump_impl.hpp" 27 | 28 | namespace handystats { namespace metrics_dump { 29 | 30 | struct dump_timestamp_visitor : public boost::static_visitor 31 | { 32 | int64_t operator() (const int& value) const { 33 | return value; 34 | } 35 | int64_t operator() (const unsigned& value) const { 36 | return value; 37 | } 38 | int64_t operator() (const int64_t& value) const { 39 | return value; 40 | } 41 | int64_t operator() (const uint64_t& value) const { 42 | return value; 43 | } 44 | int64_t operator() (const double& value) const { 45 | return value; 46 | } 47 | int64_t operator() (const bool& value) const { 48 | return 0; 49 | } 50 | int64_t operator() (const std::string& value) const { 51 | return 0; 52 | } 53 | }; 54 | 55 | void wait_until(const chrono::time_point& timestamp) { 56 | while (true) { 57 | const auto& dump = get_dump(); 58 | if (dump->find("handystats.dump_timestamp") != dump->cend()) { 59 | dump_timestamp_visitor visitor; 60 | const auto& dump_timestamp_ms = 61 | boost::apply_visitor( 62 | visitor, 63 | boost::get(dump->at("handystats.dump_timestamp")).value() 64 | ); 65 | 66 | chrono::time_point dump_timestamp(chrono::duration(dump_timestamp_ms, chrono::time_unit::MSEC), chrono::clock_type::SYSTEM); 67 | 68 | if (dump_timestamp >= timestamp) { 69 | return; 70 | } 71 | } 72 | 73 | std::this_thread::sleep_for(std::chrono::microseconds(1)); 74 | } 75 | } 76 | 77 | }} // namespace handystats::metrics_dump 78 | 79 | #endif // HANDYSTATS_TESTS_METRICS_DUMP_HELPER_HPP_ 80 | -------------------------------------------------------------------------------- /tests/scoped_counter.gtest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #include "message_queue_helper.hpp" 35 | #include "metrics_dump_helper.hpp" 36 | 37 | class HandyScopedCounterTest : public ::testing::Test { 38 | protected: 39 | virtual void SetUp() { 40 | HANDY_CONFIG_JSON( 41 | "{\ 42 | \"dump-interval\": 10\ 43 | }" 44 | ); 45 | 46 | HANDY_INIT(); 47 | } 48 | virtual void TearDown() { 49 | HANDY_FINALIZE(); 50 | } 51 | }; 52 | 53 | TEST_F(HandyScopedCounterTest, TestSingleScope) { 54 | const int COUNT = 10; 55 | 56 | for (int step = 0; step < COUNT; ++step) { 57 | HANDY_COUNTER_SCOPE("test.counter", 1); 58 | } 59 | 60 | handystats::message_queue::wait_until_empty(); 61 | handystats::metrics_dump::wait_until(handystats::chrono::system_clock::now()); 62 | 63 | auto metrics_dump = HANDY_METRICS_DUMP(); 64 | 65 | ASSERT_TRUE(metrics_dump->find("test.counter") != metrics_dump->end()); 66 | 67 | const auto& agg_stats = 68 | boost::get(metrics_dump->at("test.counter")) 69 | .values(); 70 | 71 | ASSERT_EQ(agg_stats.get(), 2 * COUNT + 1); 72 | ASSERT_EQ(agg_stats.get(), 0); 73 | ASSERT_EQ(agg_stats.get(), 1); 74 | } 75 | 76 | TEST_F(HandyScopedCounterTest, TestDoubleNestedScope) { 77 | const int COUNT = 10; 78 | 79 | for (int step = 0; step < COUNT; ++step) { 80 | HANDY_COUNTER_SCOPE("test.counter", 1); 81 | { 82 | HANDY_COUNTER_SCOPE("test.counter", -1); 83 | } 84 | } 85 | 86 | handystats::message_queue::wait_until_empty(); 87 | handystats::metrics_dump::wait_until(handystats::chrono::system_clock::now()); 88 | 89 | auto metrics_dump = HANDY_METRICS_DUMP(); 90 | 91 | ASSERT_TRUE(metrics_dump->find("test.counter") != metrics_dump->end()); 92 | 93 | const auto& agg_stats = 94 | boost::get(metrics_dump->at("test.counter")) 95 | .values(); 96 | 97 | ASSERT_EQ(agg_stats.get(), 4 * COUNT + 1); 98 | ASSERT_EQ(agg_stats.get(), 0); 99 | ASSERT_EQ(agg_stats.get(), 1); 100 | } 101 | -------------------------------------------------------------------------------- /tests/timer.gtest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) YANDEX LLC. All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | #include "json/timer_json_writer.hpp" 29 | 30 | using namespace handystats::metrics; 31 | 32 | TEST(TimerTest, CheckTimerCountsRunningTimeCorrectly) { 33 | const auto& sleep_time = std::chrono::microseconds(100); 34 | timer inter; 35 | inter.start(); 36 | 37 | std::this_thread::sleep_for(sleep_time); 38 | 39 | inter.stop(); 40 | 41 | ASSERT_GT(inter.values().get(), 42 | handystats::chrono::duration::convert_to(handystats::metrics::timer::value_unit, 43 | handystats::chrono::duration(sleep_time.count(), handystats::chrono::time_unit::USEC)).count() 44 | ); 45 | } 46 | 47 | TEST(Timer, CheckNotStartedTimerHasNoDuration) { 48 | const auto& sleep_time = std::chrono::microseconds(100); 49 | timer inter; 50 | 51 | std::this_thread::sleep_for(sleep_time); 52 | 53 | ASSERT_EQ(inter.values().get(), 0); 54 | } 55 | 56 | TEST(TimerTest, CheckNotStoppedTimerHasNoDuration) { 57 | const auto& sleep_time = std::chrono::microseconds(100); 58 | timer inter; 59 | inter.start(); 60 | 61 | std::this_thread::sleep_for(sleep_time); 62 | 63 | ASSERT_EQ(inter.values().get(), 0); 64 | } 65 | 66 | --------------------------------------------------------------------------------