{"id":32171620,"url":"https://github.com/vetspire-vsp/sibyl","last_synced_at":"2025-12-12T00:14:07.460Z","repository":{"id":44122626,"uuid":"511869663","full_name":"Vetspire-VSP/sibyl","owner":"Vetspire-VSP","description":"Easy, ergonomic telemetry \u0026 observability for Elixir applications.","archived":false,"fork":false,"pushed_at":"2025-05-01T13:29:02.000Z","size":97,"stargazers_count":72,"open_issues_count":12,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-08-12T06:44:57.136Z","etag":null,"topics":["elixir","telemetry","tracing"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Vetspire-VSP.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,"zenodo":null}},"created_at":"2022-07-08T11:24:29.000Z","updated_at":"2025-08-09T12:53:15.000Z","dependencies_parsed_at":"2023-01-23T20:15:21.236Z","dependency_job_id":"f9650228-60bf-45ff-b7a0-026d085b3004","html_url":"https://github.com/Vetspire-VSP/sibyl","commit_stats":{"total_commits":66,"total_committers":4,"mean_commits":16.5,"dds":"0.16666666666666663","last_synced_commit":"ac8a841f1853770d00c1ecba089b2d468d1eba91"},"previous_names":["vetspire-vsp/sibyl","vetspire/sibyl"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Vetspire-VSP/sibyl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Vetspire-VSP%2Fsibyl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Vetspire-VSP%2Fsibyl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Vetspire-VSP%2Fsibyl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Vetspire-VSP%2Fsibyl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Vetspire-VSP","download_url":"https://codeload.github.com/Vetspire-VSP/sibyl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Vetspire-VSP%2Fsibyl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280308477,"owners_count":26308492,"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","status":"online","status_checked_at":"2025-10-21T02:00:06.614Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["elixir","telemetry","tracing"],"created_at":"2025-10-21T17:54:20.058Z","updated_at":"2025-10-21T17:54:25.169Z","avatar_url":"https://github.com/Vetspire-VSP.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sibyl\n\n[![hex.pm](https://img.shields.io/hexpm/v/sibyl.svg)](https://hex.pm/packages/sibyl)\n[![hexdocs.pm](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/sibyl/)\n[![hex.pm](https://img.shields.io/hexpm/dt/sibyl.svg)](https://hex.pm/packages/sibyl)\n[![hex.pm](https://img.shields.io/hexpm/l/sibyl.svg)](https://hex.pm/packages/sibyl)\n\nEasy, ergonomic telemetry \u0026 observability for Elixir applications.\n\n## Why\n\nSibyl aims to solve three main problems:\n\n1. It isn't always clear how best to emit telemetry events in your Elixir projects as `:telemetry` is rather low level, and a lot of examples focus on library code.\n2. Telemetry \u0026 observability is either too high level, or requires a lot of mainly instrumentation which can be noisy and be error-prone when done manually.\n3. Emitting events/telemetry and consuming them are seperated concerns. You're on your own for deciding how to consume the events you do emit in your code.\n\nThe above is actually great for building libraries where you want to emit events and allow external users to consume said events, and do so in an unopinionated\nway. However, applications tend to emit events explicitly so that they can be consumed, and tend to want to do so in an opinionated or constrained way.\n\nSibyl tries to solve the above by being a light wrapper around `:telemetry` and embracing OpenTelemetry.\n\n## Installation\n\nAdd `:sibyl` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:sibyl, \"~\u003e 0.1.0\"}\n  ]\nend\n```\n\nCurrently, Sibyl requires Elixir 1.15 or higher. We aim to support Sibyl for the three most recent Elixir major releases at any given time.\n\n## Usage\n\nSibyl is an opinionated library that aims to get you tracing your code and emitting metrics with minimal instrumentation as quickly as possible!\n\nBefore actually emitting any metrics/events in your code, you need to configure Sibyl to automatically start up by adding the following to your\nproject's `Application` module:\n\n```elixir\ndefmodule MyApp.Application do\n  use Application\n\n  def start(_type, _args) do\n    ...\n  after\n    :ok = Sibyl.Handlers.attach_all_events(Sibyl.Handlers.OpenTelemetry)\n  end\nend\n```\n\n### Tracing Functions\n\nYou can start tracing functions, capturing their runtime, return values, exceptions, and more by using the `trace/0` macro with the `@decorate` directive\nwhich is provided to any module that has `use Sibyl` in it.\n\nTraced functions automatically emit `:telemetry` events when they initially get called, when they end, and when they throw an exception. Sibyl will\ncapture the time elapsed, arguments provided, return value, and any events (and their measurements, metadata) emitted during the function.\n\n```elixir\ndefmodule MyApp.Users do\n  alias MyApp.User\n  alias MyApp.Repo\n\n  use Sibyl\n\n  @decorate trace()\n  def register(attrs) do\n    attrs\n    |\u003e User.changeset()\n    |\u003e Repo.insert()\n    |\u003e case do\n      {:ok, user} -\u003e\n        {:ok, user}\n\n      {:error, reason} -\u003e\n        {:error, reason}\n    end\n  end\nend\n```\n\n### Tracing Modules\n\nTypically, we recommend that functions be traced with purpose to minimize noise, however, Sibyl is able to automatically trace every function defined in a\nmodule that using the `trace/0` macro with the `@decorate_all` directive instead of `@decorate`.\n\n```elixir\ndefmodule MyApp.Users do\n  use Sibyl\n\n  @decorate_all trace()\n\n  def register(attrs) do\n    attrs\n    |\u003e User.changeset()\n    |\u003e Repo.insert()\n    |\u003e case do\n      {:ok, user} -\u003e\n        {:ok, user}\n\n      {:error, reason} -\u003e\n        {:error, reason}\n    end\n  end\nend\n```\n\n### Emitting Events\n\nAdditionally, aside from tracing the runtime and state of your functions, Sibyl also makes it easy to emit arbitrary events\nand metrics in your application.\n\nUnlike using the standard `:telemetry` library directly, Sibyl will ensure that any event being emitted was previously defined\nby Sibyl at compile time. This guarantees that events that are emitted exist, and makes your events durable across refactors and\nrenaming.\n\nYou can define events with the `define_event/1` macro which is automatically imported whenever you `use Sibyl`, and you can\nemit them via the `emit/1` macro:\n\n```elixir\ndefmodule MyApp.Users do\n  use Sibyl\n\n  define_event(:registration)\n  define_event(:registration_failed)\n\n  def create_user(attrs) do\n    attrs\n    |\u003e User.changeset()\n    |\u003e Repo.insert()\n    |\u003e case do\n      {:ok, user} -\u003e\n        emit(:registration)\n        {:ok, user}\n\n      {:error, changeset} -\u003e\n        emit(:registration_failed)\n        {:error, changeset}\n    end\n  end\nend\n```\n\nAlternatively, events can be defined in other modules and emitted by referencing the definer such as:\n\n```elixir\ndefmodule MyApp.Events do\n  use Sibyl\n\n  define_event(:function_executed)\n  define_event(:api_key_requests)\n  define_event(:user_requests)\nend\n\ndefmodule MyApp.Users do\n  use Sibyl\n  alias MyApp.Events\n\n  def create_user(attrs) do\n    emit(Events, :function_executed)\n    if is_api_user(self())?, do: emit(Events, :api_key_requests),\n                             else: emit(Events, :user_requests)\n\n    attrs\n    |\u003e User.changeset()\n    |\u003e Repo.insert()\n  end\nend\n```\n\n### Plugins\n\nBecause Sibyl builds on top of the de-facto telemetry library for the BEAM, it's able to provide an easy way to extend\nthe events Sibyl is able to handle via first class plugins.\n\nYou can configure plugins on a handler by handler basis via the following configuration:\n\n```elixir\ndefmodule MyApp.Application do\n  use Application\n\n  def start(_type, _args) do\n    ...\n  after\n    :ok = Sibyl.Handlers.attach_all_events(Sibyl.Handlers.OpenTelemetry, plugins: [\n      Sibyl.Plugins.Absinthe,\n      Sibyl.Plugins.Ecto,\n      ...\n    ])\n  end\nend\n```\n\nSee the [documentation](https://hexdocs.pm/sibyl/) for more information.\n\n### Runtime Tracing\n\nSibyl is additionally able to trace and handle `:telemetry` events entirely at runtime, with no orchestration needed\nat all!\n\nThis is done by leveraging the BEAM's built in `trace/3` BIFs, mapping internal BEAM events to `:telemetry` alike event\nemissions.\n\nUsing `Sibyl.Dynamic` looks like the following:\n\n```elixir\niex\u003e Sibyl.Dynamic.enable(Sibyl.Handlers.OpenTelemetry)\niex\u003e Sibyl.Dynamic.trace(MyApp.Users, :create_user, 1)\niex\u003e MyApp.Users.create_user(%{email: \"test\"}) # Emits Sibyl-compatible `:telemetry` events\n{:ok, %MyApp.User{}}\n```\n\n## Additional Features\n\nSee the [documentation](https://hexdocs.pm/sibyl/) for more exhaustive information about Sibyl's features, but other features\nnot covered by the above includes:\n\n- Open and extendable `Sibyl.Handler` behaviour for defining alternative handlers\n- Speedscope and Chrome compatible flamegraph handler via `Sibyl.Handlers.FlameGraph`\n- More soon!\n\n## Contributing\n\nWe enforce 100% code coverage and a strict linting setup for Sibyl.\n\nPlease ensure that commits pass CI. You should be able to run both `mix test` and `mix lint` locally.\n\nSee the `mix.exs` to see the breakdown of what these commands do.\n\nAdditionally, we develop Sibyl using tools to manage our Elixir versions such as [`asdf`](https://asdf-vm.com) or [`nix`](https://nixos.org).\nPlease see [`.tool-versions`](./tool-versions) or [`shell.nix`](./shell.nix) accordingly.\n\n## License\n\nSee [LICENSE.md](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvetspire-vsp%2Fsibyl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvetspire-vsp%2Fsibyl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvetspire-vsp%2Fsibyl/lists"}