{"id":40570860,"url":"https://github.com/kongo2002/statser","last_synced_at":"2026-01-21T01:35:16.072Z","repository":{"id":22889181,"uuid":"85994553","full_name":"kongo2002/statser","owner":"kongo2002","description":"distributed graphite-like metrics backend written in erlang","archived":false,"fork":false,"pushed_at":"2023-03-04T04:02:39.000Z","size":1375,"stargazers_count":8,"open_issues_count":11,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-04-15T08:06:58.271Z","etag":null,"topics":["carbon","erlang","grafana","graphite","metrics","statsd","whisper"],"latest_commit_sha":null,"homepage":null,"language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kongo2002.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}},"created_at":"2017-03-23T20:29:35.000Z","updated_at":"2024-04-15T08:06:58.272Z","dependencies_parsed_at":"2023-01-13T22:23:49.725Z","dependency_job_id":null,"html_url":"https://github.com/kongo2002/statser","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/kongo2002/statser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kongo2002%2Fstatser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kongo2002%2Fstatser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kongo2002%2Fstatser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kongo2002%2Fstatser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kongo2002","download_url":"https://codeload.github.com/kongo2002/statser/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kongo2002%2Fstatser/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28621816,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T23:49:58.628Z","status":"ssl_error","status_checked_at":"2026-01-20T23:47:29.996Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["carbon","erlang","grafana","graphite","metrics","statsd","whisper"],"created_at":"2026-01-21T01:35:15.383Z","updated_at":"2026-01-21T01:35:16.066Z","avatar_url":"https://github.com/kongo2002.png","language":"Erlang","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# statser\n\n[![build status](https://api.travis-ci.org/kongo2002/statser.svg)][travis]\n\nThis project is a rework of the [graphite][graphite] stack in shape of an erlang\napplication.\n\n\u003e The project is still in beta state - work in progress but feel free to\n\u003e give it a shot!\n\n\n## Motivation\n\n[Graphite][graphite] is a fantastic piece or rather collection of software(s)\nthat's tough to 'replace' at all. Nonetheless there are a few points\nthat motivate me to tackle some parts of [graphite][graphite]'s feature set to\nbe solved in a distributed erlang-powered application.\n\n- the fact that the \"graphite stack\" is spread across several applications\n  (`whisper`, `carbon`, `graphite-web`) has some advantages for sure but\n  complicates maintainability significantly\n\n- as soon as you want/have to distribute graphite across multiple nodes there\n  come more application parts into play (`carbon-relay`, `carbon-aggregator`)\n\n- all of these applications are configured independently from each other and\n  might get difficult to tune into sync at times\n\n- *statser* will be built to replace basically all of the \"server parts\" into\n  one single application which is supposed to be distributed more easily (erlang\n  is basically built for this kind of thing)\n\n- my goal is that you only need one or more `statser` instances that expose an\n  interface that can be used with common metrics dashboards like\n  [grafana][grafana] - and nothing more!\n\n- last but not least I will use this project to improve my grip on erlang for\n  sure\n\n\n## Build\n\n### Requirements\n\n* erlang OTP \u003e= 20\n  * xmerl\n* node-js *(for client only)*\n\n\n### Compile\n\nYou can build the project's components by using the `Makefile`:\n\n    $ make\n\nThe server and client parts can also be built separately:\n\n    $ make server\n    $ make client\n\nHowever since the project is powered by [rebar3][rebar3], you may also directly\ninvoke all common commands directly:\n\n    $ rebar3 compile\n\n\n### Docker\n\nYou can also use the pre-built [docker\nimage](https://hub.docker.com/r/kongo2002/statser/) in order to quickly get up\nand running:\n\n    $ docker pull kongo2002/statser\n\nOn your local machine you may want to start the container with `-P` or expose\nthe container's ports on your host machine:\n\n    $ docker run -d -p 8080:8080 -p 2003:2003 -p 8125:8125/udp kongo2002/statser\n\n\n### Quickstart\n\nAfter successful compilation you can quickly start a development *statser*\ninstance with the sample `start.sh` script. The script uses default options that\nspawn port `2003` (carbon plain text interface), port `8080` (metrics API) and\n`8125/udp` (StatsD interface):\n\n    $ ./start.sh\n\nNow you can already ingest metrics, e.g. by using `netcat`:\n\n```bash\n# push some test metrics\n$ echo \"test.foo 100.1\" | nc --send-only localhost 2003\n$ echo \"test.bar 200.2\" | nc --send-only localhost 2003\n\n# fetch metrics\n$ curl localhost:8080 -XPOST -d 'target=test.*' -d 'maxDataPoints=5'\n[{\"target\":\"test.bar\",\n  \"datapoints\":[[null,1520891400],[null,1520908680],[null,1520925960],[null,1520943240],[200.2,1520960520]]},\n {\"target\":\"test.foo\",\n  \"datapoints\":[[null,1520891400],[null,1520908680],[null,1520925960],[null,1520943240],[100.1,1520960520]]}]\n```\n\n\n#### Web dashboard\n\nMoreover you can browse to the web dashboard that displays some of statser's\nhealth endpoints, internal metrics and serves a basic administration UI:\n\n    $ firefox http://localhost:8080/.statser/\n\n\n### Tests\n\n    # basically the same as `rebar3 eunit`\n    $ make test\n\n\n## Status\n\nRight now you can start `statser` which will listen on port `2003` (by default)\nand for example start your `collectd` instance(s) (or whatever graphite\ncompatible metrics source you use), point those to your `statser` node and it\nwill go ahead with recording and aggregating your metrics just like\n`carbon-cache` did. Moreover you can configure the storage and aggregation rules\nin a simple YAML configuration file.\n\nMoreover you can already point your [grafana][grafana] dashboard to your statser\ninstance just like you did with a graphite backend. Even though\n[grafana][grafana] has no particular statser-support it does work because\nstatser implements (or mimics) most parts of graphite-web's API already.\n\nFind a list of features that are either finished or on my roadmap below.\n\n\n### Features\n\n* full whisper database support\n* carbon plain text interface (known to listen on port `2003`)\n* configurable storage rules\n* configurable aggregation schemes\n* throttling of archive creation\n* throttling of metrics updates (writes to disk)\n* configurable blacklist/whitelist of metrics\n* basic [StatsD][statsd] interface (known to listen on UDP port `8125`)\n    - support for counters, timers, gauges and sets\n* support for querying metrics of multiple connected statser instances\n* metrics API\n* render API (JSON output only!)\n    - `absolute`\n    - `aliasByMetric`\n    - `aliasByNode`\n    - `aliasSub`\n    - `alias`\n    - `asPercent`\n    - `averageAbove`\n    - `averageBelow`\n    - `averageOutsidePercentile`\n    - `averageSeries` (short alias: `avg`)\n    - `changed`\n    - `constantLine`\n    - `currentAbove`\n    - `currentBelow`\n    - `derivative`\n    - `diffSeries`\n    - `divideSeries`\n    - `exclude`\n    - `grep`\n    - `highestAverage`\n    - `highestCurrent`\n    - `highestMax`\n    - `integralByInterval`\n    - `integral`\n    - `invert`\n    - `isNonNull`\n    - `keepLastValue`\n    - `limit`\n    - `lowestAverage`\n    - `lowestCurrent`\n    - `maxSeries`\n    - `maximumAbove`\n    - `maximumBelow`\n    - `minSeries`\n    - `minimumAbove`\n    - `minimumBelow`\n    - `mostDeviant`\n    - `movingAverage`\n    - `multiplySeries`\n    - `nPercentile`\n    - `nonNegativeDerivative`\n    - `offsetToZero`\n    - `offset`\n    - `perSecond`\n    - `powSeries`\n    - `pow`\n    - `randomWalk`\n    - `rangeOfSeries`\n    - `removeAboveValue`\n    - `removeBelowValue`\n    - `scaleToSeconds`\n    - `scale`\n    - `squareRoot`\n    - `stddevSeries`\n    - `sumSeries`\n\n\n### Configuration\n\nStatser ships with sane defaults out-of-the-box so you might not need a\nconfiguration at all. However there are a few settings that you may configure\nvia a YAML file (`statser.yaml` in the working directory):\n\n```yaml\n# storage directory of the whisper files\n# defaults to the current working directory\ndata_dir: /opt/whisper/storage\n\n# IO consuming operations like updates and archive creations\n# are by default (and should be) rate limited to some extent:\nrate_limits:\n\n  # max. archive creations per second (default: 25)\n  creates: 25\n\n  # max. archive updates per second (default: 500)\n  updates: 500\n\n# configuration of storage rules and archive retentions\n#\n# this contains basically what you might know of `storage-schemas.conf`\n# from the 'carbon-cache' configuration\nstorage:\n\n  stats:\n    pattern: ^stats\\.\n    retentions:\n      - 10:1m\n      - 60:1d\n\n  carbon:\n    pattern: ^carbon\\.\n    retentions:\n      - 60:30d\n\n# storage aggregation rules\n#\n# may look familiar to `storage-aggregation.conf` of carbon-cache\naggregation:\n\n  min:\n    pattern: \\.min$\n    aggregation: min\n    factor: 0.1\n\n  max:\n    pattern: \\.max$\n    aggregation: max\n    factor: 0.1\n\n  count:\n    pattern: \\.count$\n    aggregation: sum\n    factor: 0\n\n# you may configure a blacklist and/or whitelist to configure\n# what metrics you really care about\n# every metric that enters the system will be checked against\n# the regexes you defined\nblacklist:\n  - \\.sum_squares$\n  - \\.localhost\\.\n\nwhitelist:\n  - ^stats\\.\n\n# metrics and render API\napi:\n  port: 8080\n\n# TCP listener\n# this listener is basically equivalent to the carbon\n# plaintext listener you might know from graphite\ntcp:\n  port: 2003\n\n# StatsD compatible adapter\nudp:\n  # UDP port to listen on\n  # set this to something =\u003c 0 to disable\n  port: 8125\n\n  # metrics flush interval (in seconds)\n  interval: 10\n\n  # prune inactive metrics keys after x seconds\n  # 0 to never prune metrics at all\n  prune_after: 300\n\n# protobuf listener (disabled by default)\n#\n# the protobuf interface was introduced in graphite 1.x\n# you can enable this by using the following options\nprotobuf:\n  port: 2005\n```\n\n\n### TODO\n\n* graphite 1.1 features\n  - tag support\n  - [open metrics format][openmetrics]\n* support even more functions of `graphite-web` render API\n* investigate into more elaborate archive write optimization\n\n\n## License\n\n*statser* is licensed under the [Apache license][apache], Version 2.0\n\n\u003e Unless required by applicable law or agreed to in writing, software\n\u003e distributed under the License is distributed on an \"AS IS\" BASIS,\n\u003e WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\u003e See the License for the specific language governing permissions and\n\u003e limitations under the License.\n\n\n[apache]: http://www.apache.org/licenses/LICENSE-2.0\n[docker]: https://www.docker.com/\n[grafana]: https://grafana.com/\n[graphite]: https://graphiteapp.org/\n[openmetrics]: https://github.com/RichiH/OpenMetrics/blob/master/metric_exposition_format.md\n[rebar3]: https://www.rebar3.org/\n[statsd]: https://github.com/etsy/statsd/\n[travis]: https://travis-ci.org/kongo2002/statser/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkongo2002%2Fstatser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkongo2002%2Fstatser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkongo2002%2Fstatser/lists"}