{"id":19486048,"url":"https://github.com/appliscale/xprof","last_synced_at":"2025-05-16T16:03:32.173Z","repository":{"id":2187715,"uuid":"43468116","full_name":"Appliscale/xprof","owner":"Appliscale","description":"A visual tracer and profiler for Erlang and Elixir.","archived":false,"fork":false,"pushed_at":"2024-02-23T00:06:38.000Z","size":13418,"stargazers_count":279,"open_issues_count":51,"forks_count":33,"subscribers_count":30,"default_branch":"master","last_synced_at":"2025-04-03T13:17:22.976Z","etag":null,"topics":["capture","elixir","erlang","erlang-otp","erlang-vm","hex","profiling","tool","tracing","tracking"],"latest_commit_sha":null,"homepage":"","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Appliscale.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-10-01T00:07:21.000Z","updated_at":"2025-04-01T00:47:43.000Z","dependencies_parsed_at":"2023-12-20T13:25:37.941Z","dependency_job_id":"135642d9-50e0-41d4-8c12-d0559a20f2ed","html_url":"https://github.com/Appliscale/xprof","commit_stats":{"total_commits":478,"total_committers":15,"mean_commits":"31.866666666666667","dds":0.50418410041841,"last_synced_commit":"fb2611255a6585b692c99be028d02d811cfbb9a1"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Appliscale%2Fxprof","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Appliscale%2Fxprof/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Appliscale%2Fxprof/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Appliscale%2Fxprof/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Appliscale","download_url":"https://codeload.github.com/Appliscale/xprof/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248578875,"owners_count":21127714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["capture","elixir","erlang","erlang-otp","erlang-vm","hex","profiling","tool","tracing","tracking"],"created_at":"2024-11-10T20:33:24.298Z","updated_at":"2025-04-12T14:20:07.259Z","avatar_url":"https://github.com/Appliscale.png","language":"Erlang","readme":"XProf [![Build Status](https://travis-ci.org/Appliscale/xprof.svg?branch=master)](https://travis-ci.org/Appliscale/xprof) [![Coverage Status](https://coveralls.io/repos/github/Appliscale/xprof/badge.svg?branch=master)](https://coveralls.io/github/Appliscale/xprof?branch=master) [![Hex.pm](https://img.shields.io/hexpm/v/xprof.svg?style=flat-square)](https://hex.pm/packages/xprof) [![Hex.pm](https://img.shields.io/hexpm/dt/xprof.svg?style=flat-square)](https://hex.pm/packages/xprof) [![Gitter](https://badges.gitter.im/Appliscale/xprof.svg)](https://gitter.im/Appliscale/xprof?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\n=====\n\n*XProf* is a visual tracer and profiler that allows you to track execution of Elixir / Erlang\nfunctions in real-time.\n\n## Goal\n\n*XProf* was originally created to help solving performance problems of live, highly\nconcurrent and utilized back-end systems. It's often the case that high latency or big\nCPU usage is caused by very specific requests that are triggering\ninefficient code. Finding this code is usually pretty difficult.\n\nIn this original usage one would first inspect execution time\nstatistics to get an overview of the system. Then capture arguments\nand results (return value or exception) of function calls that lasted\nlonger than given number of milliseconds.\n\nWith the introduction of xprof-commands via an extended query syntax in\n2.0 more versatile stats, filters and other features became available.\n\n## How does it look like\n\nClick the image below to watch a short demo investigating the `TryMe`\napplication with XProf. The function `nap` sometimes takes way too much time (as\nyou would guess from the name, it takes a bit of sleep). In the video we:\n- observe call count and duration percentiles\n- capture arguments and return values of a few long calls\n- apply a match spec to filter out \"long\" calls\n- compare two functions\n\n[![XProf Demo](doc/assets/xprof_demo_1.2.1_screenshot.png)](https://youtu.be/CRPC6zloDS0 \"XProf Demo\")\n\n## How to use it\n\n1. Add `xprof` to your build tool config file (and optionally also to the\n   release config file such as `reltool.config` in order to include it in your\n   release).\n2. Build your project.\n3. Start `xprof` by executing `xprof:start().` in Erlang shell,\n   or `:xprof.start` in Elixir shell.\n4. Go to http://localhost:7890 (replace localhost with your server’s hostname if you connect to a remote host).\n5. Type in function that you would like to start tracing.\n6. Start tracing clicking green button.\n\nThe preferred way is to add the `xprof` *Hex* package as a dependency to your rebar3 config or Mix project file:\n\n```erlang\n%% rebar.config (at least version `3.3.3` is required):\n\n{deps, [\n       ...\n       {xprof, \"2.0.0-rc.5\"}\n]}.\n```\n\n```elixir\n# `mix.exs`:\n\ndefp deps do\n    [\n      ...\n      {:xprof, \"~\u003e 2.0.0-rc.5\"}\n    ]\n  end\n```\n\nYou can also fetch from the github repository (not recommended, only for development, requires rebar 3.14):\n\n```erlang\n{deps, [\n        ...\n        {xprof_core, {git_subdir, \"https://github.com/Appliscale/xprof.git\", {tag, \"2.0.0-rc.5\"}, \"apps/xprof_core\"}},\n        {xprof_gui, {git_subdir, \"https://github.com/Appliscale/xprof.git\", {tag, \"2.0.0-rc.5\"}, \"apps/xprof_gui\"}},\n        {xprof, {git_subdir, \"https://github.com/Appliscale/xprof.git\", {tag, \"2.0.0-rc.5\"}, \"apps/xprof\"}}\n]}.\n```\n\n## Supported Versions\n\nXProf currently supports Erlang/OTP 18 - 26. Newer OTP versions (if\nany) might work but are not tested.\n\n## Syntax mode\n\nXProf supports both Erlang and Elixir syntax. If the `elixir` application is\nrunning it will use Elixir syntax and Erlang syntax otherwise to read the\nfunction to trace and to print captured arguments. It is also possible to\nmanually set the preferred mode.\n\n## XProf flavoured match-spec funs\n\nIn the function browser apart from simple module-function-arity you\ncan also specify further filters in the form of a match-spec functions\n(similar to recon or redbug) as well as xprof commands with\noptions. For details see the page on [Query syntax](doc/src/querysyntax.md)\n\n## Recursive functions\n\nBy default XProf only measures the outermost call to a recursive function. For\nexample `lists:map(fun f/1, [1, 2, 3]).` will only register one call to\n`lists:map/2`. This is also true for indirectly recursive functions (such as\nwhen `a` calls `b` and `b` calls `a` again). This behaviour can be undesirable\nso it can be disabled by setting the `ignore_recursion` environment variable to\nfalse.\n\n## Erlang records\n\nErlang record syntax is supported in the queries and works similar to the Erlang\nshell. XProf keeps a single global list of loaded record definitions. Record\ndefinitions can be loaded at startup time from modules listed in app env\n`load_records` or at runtime calling `xprof_core:rr(Module)` (see documentation\nof `xprof_core` for more details). The record definitions are extracted from\ndebug_info of the beam files belonging to the loaded modules. As the list is\nglobal there can be only one record with the same name loaded at a time and\nrecords loaded later might override previously loaded ones.\n\n## Configuration\n\nYou can configure XProf by changing the below application variables:\n\n| Application  | Key                    | Default        | Description |\n|--------------|------------------------|----------------|-------------|\n| `xprof_gui`  | `ip`                   | any            | Listen address of the web interface (in tuple format, see [`inet:ip_address()`](http://erlang.org/doc/man/inet.html#type-ip_address)) |\n| `xprof_gui`  | `port`                 | 7890           | Port for the web interface |\n| `xprof_gui`  | `favourites_enabled`   | true           | Whether saving/loading favourite queries is enabled |\n| `xprof_gui`  | `favourites_config`    | ./favourites.cfg | Path of the file storing favourite queries |\n| `xprof_core` | `max_tracer_queue_len` | 1000           | Overflow protection. If main tracer process will have more than 1000 messages in its process queue tracing will be stopped and one needs to use trace button to resume. The purpose of this is to prevent out of memory crashes when tracer process is not able to process incoming traces fast enough. This may happen when we trace very \"hot\" function. |\n| `xprof_core` | `max_duration`         | 30000          | The largest duration value in ms. In case a call takes even longer, this maximum value is stored instead. |\n| `xprof_core` | `ignore_recursion`     | true           | Whether to only measure the outermost call to a recursive function or not (ie. measure all calls). |\n| `xprof_core` | `mode`                 | \u003cautodetected\u003e | Syntax mode (`erlang` or `elixir`) |\n| `xprof_core` | `load_records`         | []             | List of modules from which to load record definitions at startup. |\n\n## Compile-time configuration\n\n`XPROF_ERL_HIST` - By default XProf uses the `hdr_histogram_erl` NIF\nlibrary. If you have compilation problems you can choose to use a\nnative Erlang histogram implementation by defining the OS env var\n`XPROF_ERL_HIST` when compiling `xprof_core`.\n\n`COWBOY_VERSION` - By default XProf uses Cowboy version 2.x. This\nversion is only supported from Erlang/OTP 19 and is not backwards\ncompatible with older Cowboy versions. If for some reason you would\nlike to use Cowboy version 1.x you can define the OS env var\n`COWBOY_VERSION=1` when compiling `xprof_gui`.\n\n`XPROF_JSON_LIB` - By default XProf uses the `jsone` library. If you\nwould like to use a different json library you can define the OS env\nvar `XPROF_JSON_LIB` when compiling `xprof_gui`. It is assumed that\nthe library module exports an `encode/1` function that returns the\nencoded binary. If your preferred json library uses a different name\nfor such a function, you can set it with `XPROF_JSON_ENC_FUN`.\n\nExamples\n\n```\nexport XPROF_ERL_HIST=true\nexport COWBOY_VERSION=1\nexport XPROF_JSON_LIB='Elixir.Jason'\nexport XPROF_JSON_ENC_FUN='encode!'\n```\n\n## Web Interface\n\nXProf's web interface supports a lot of small but convenient features\nas query autocomplition, recent queries, favourite queries, list of\ncalled functions, collapsing graphs, multiple graphs in a row and so\non.\n\n### Keyboard shortcuts\n\n- **Ctrl-i**: switch between \"search\" and \"favourites\" mode of the query box\n\nIn \"search\" mode\n- **UP**/**DOWN** arrows (cursor in query box): scroll through recent queries\n- **UP**/**DOWN** arrows (cursor in suggestion list below query box): scroll\n  through auto-completion suggestions\n- **TAB**: if no suggetion is selected yet auto-complete to longest common\n  prefix of dropdown list items. Otherwise copy the selected item to the search\n  box and refresh the dropdown list.\n- **ENTER**: start monitoring either the selected suggestion if there is any or the\n  expression in the search box.\n\nIn \"favorites\" mode\n- Search only starts after typing the second character. (For 0 and 1\n  chars you see the list of all favorite queries)\n- **UP**/**DOWN** arrows: scroll through the list\n- **ENTER**: start monitoring highlighted query if there is any (also\n  added to recent queries)\n- **ESC**: reset search (clear the query box and hide the list)\n- **TAB**: show full list of favourite queries, when the query box is\n  empty and the list isn't visible\n\n## Contributing\n\nAll improvements, fixes and ideas are very welcomed!\n\nProject uses rebar3 for building and testing Erlang code. WebUI part resides in\n`xprof_gui` app's priv directory and it's already precompiled so there is no need to\nbuild JS sources in order to run `xprof`.\n\n### Running tests\n\n```bash\nmake test\n```\n\n### Working with JS sources\n\nThe WebUI uses\n\n* *React.js*\n* *ECMAScript 6* (with elements from *7th* version).\n* *Bootstrap*\n* *Webpack*\n\nAll resources are in `apps/xprof_gui/priv` directory. The `src` folder contains the sources and\nthe `build` folder is a placeholder for final JS generated by webpack and then\nserved by cowboy server (*XProf's* dependency).\n\n### Starting XProf in development mode\n\nTo develop `xprof` in a convenient way the following setup is recommended.\n\nYou have to invoke following command once, if you do not have js dependencies or\nyou need to update them:\n\n```bash\n$ make bootstrap_front_end\n```\n\nThen going with normal development flow - in the first terminal window\nstart Erlang `xprof`. The _sync_ app will be started, It automatically\nreloads erlang modules that have changed, so you don't need to\nrecompile every time something changed.\n\n```bash\n$ make dev_back_end\n```\n\nIn the second window install all the assets and start *webpack* in\ndevelopment mode which is also going to recompile all *JS* files into\n`apps/xprof_gui/priv/build-dev` directory when they are modified. To\nachieve that use following command:\n\n```bash\n$ make dev_front_end\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappliscale%2Fxprof","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fappliscale%2Fxprof","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappliscale%2Fxprof/lists"}