[![Build Status](https://travis-ci.org/amzn/hawktracer.svg?branch=master)](https://travis-ci.org/amzn/hawktracer) [![Gitter chat](https://img.shields.io/gitter/room/amzn/hawktracer.svg)](https://gitter.im/amzn/hawktracer) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/8d0f18c7a6b14f15bb747b0a4cd336bb)](https://www.codacy.com/app/loganek/hawktracer?utm_source=github.com&utm_medium=referral&utm_content=loganek/hawktracer&utm_campaign=Badge_Grade) [![codecov](https://codecov.io/gh/loganek/hawktracer/branch/master/graph/badge.svg)](https://codecov.io/gh/loganek/hawktracer) [![Build status](https://ci.appveyor.com/api/projects/status/3yh0rvyxs0x38802?svg=true)](https://ci.appveyor.com/project/loganek/hawktracer) # HawkTracer HawkTracer is a highly portable, low-overhead, configurable profiling tool built in Amazon Video for getting performance metrics from low-end devices. HawkTracer is available on most popular platforms: **Linux**, **Windows**, **OS X**. By default, the library can be used with **C** and **C++**, but there are also wrappers for [**Python**](bindings/python3) and [**Rust**](https://github.com/AlexEne/rust_hawktracer). The library provides many different types of events (e.g. CPU usage event, duration tracepoint), but the list can easily be extended by the user. ## Features * Low CPU/memory overhead * Multi-platform * Highly configurable on runtime * Easy build integration (CMake & pkg-config files) * Pre-defined and user-defined events * Simple macros for code instrumentation * Streaming events to file, through TCP/IP protocol, or handling them in custom function * Client for receiving event stream * Library for parsing event stream (so you can write your own client) ## License Summary This sample code is made available under the MIT license. (See [LICENSE](LICENSE) file) ## Getting Started ### Hello World! tutorials See [the tutorial](https://www.hawktracer.org/doc/stable/tutorial_hello_world.html) to quickly onboard to HawkTracer or check the [examples](examples/) directory. The tutorial step by step explains how to build and instrument the code like that: ```cpp static void hello_world() { HT_TP_G_FUNCTION() for (int i = 0; i < 100; i++) { HT_TP_G_STRACEPOINT("iteration") printf("2 * %d = %d\n", i, 2*i); std::string txt = "Iteration (mod 10): " + std::to_string(i % 10); HT_TP_G_DYN_STRACEPOINT(txt.c_str()); printf("text: %s\n", txt.c_str()); } } ``` You can also follow instructions below to get HawkTracer up and running. ### Building library ```bash $ mkdir build # It'll be different on Windows $ cd build $ cmake .. $ cmake --build . # This instead of make, so we don't need extra instructions for Windows ``` ## Attaching HawkTracer to a project to profile ### Build system integration #### CMake-based projects If you use CMake build system, you can use following code to attach HawkTracer library to your project: ```cmake project(your_project) # optionally, you might define a path to HawkTracer's CMake module # CMake the path below should be a path to a directory where HawkTracerConfig.cmake is located, e.g.: # list(APPEND CMAKE_MODULE_PATH "/usr/local/lib/cmake/HawkTracer") find_package(HawkTracer REQUIRED) add_executable(your_project main.cc) target_link_libraries(your_project HawkTracer::hawktracer) ``` #### pkg-config HawkTracer library provides pkg-config file which can be used to find required libraries and include paths. You can simply integrate it e.g. with your compilation command: ```bash $ g++ my_project.cpp $(pkg-config --cflags --libs hawktracer) ``` ### Instrumenting code #### Initialize library Before you start profiling your code, you need to initialize HawkTracer library. There are 2 functions which always have to be called in projects profiled by HawkTracer: `ht_init` and `ht_deinit`. Additionally, you need to specify an event listener. HawkTracer currently provides 2 listeners: * TCP listener, which streams events over the network * File dump listener, which saves events to a file. Moreover, HawkTracer allows to provide user-defined listeners. Code below presents example HawkTracer (un)initialization: ```cpp int main(int argc, char** argv) { ht_init(argc, argv); // initialize library HT_Timeline* timeline = ht_global_timeline_get(); // timeline, where all events are posted. You can define your own timeline, or use global timeline const size_t buffer_size = 4096; // size of internal listener's buffer ht_file_dump_listener_register(ht_global_timeline_get(), "hello-world-out.htdump", 2048, NULL); // create listener and attach it to timeline // your code goes here... ht_deinit(); // uninitialize library return 0; } ``` The code registers file dump listener, which saves all the events to a file `file_name.htdump`. The file should be then converted to a viewer's format ([see here for details](#collect-the-data)). #### Instrumenting the code HawkTracer requires explicit code instrumentation. The library provides a few helper macros for reporting data to a timeline: ```cpp // Pushes any type of event to a timeline HT_TIMELINE_PUSH_EVENT(TIMELINE, EVENT_TYPE, EVENT_PARAMETERS,...) // Reports a duration of specific block of code (available only for C++ or C GNU compiler) HT_TRACE(TIMELINE, LABEL) // The same as above, but automatically sets label to current function name HT_TRACE_FUNCTION(TIMELINE) ``` There are few macros which report events to a global timeline, they're prefixed with `G_`: ```cpp HT_G_TRACE(LABEL) HT_G_TRACE_OPT_STATIC(LABEL) HT_G_TRACE_OPT_DYNAMIC(LABEL) HT_G_TRACE_FUNCTION() ``` For example, you can instrument following code: ```cpp void foo() { HT_G_TRACE_FUNCTION() // measure duration of foo function execution for (int i = 0; i < 100; i++) { HT_G_TRACE_OPT_STATIC("in-loop") // measure duration of single loop iteration bar(); } } ``` ### Collect the data For now HawkTracer provides a simple application for converting event stream to a JSON format which can be consumed by the viewing application: `hawktracer-to-json`. You can use it with a file or with a network stream. Assuming your events have been saved to `file_name.htdump` file, you can generate the JSON file running following command: ```bash hawktracer-to-json --source file_name.htdump --output output_file.json ``` ### Analyzing the data * Install google-chrome or chromium browser * Open the browser, and open [chrome://tracing/](chrome://tracing) webpage * Click load button and open file generated in the previous section * You should see a callstack with timing ## Contributing Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us. ## Acknowledgment * Hat tip to anyone who's code was used * Inspiration * etc