{"id":13837959,"url":"https://github.com/c-cube/ocaml-trace","last_synced_at":"2025-03-16T21:31:08.124Z","repository":{"id":173953104,"uuid":"651313167","full_name":"c-cube/ocaml-trace","owner":"c-cube","description":"Common interface for tracing/instrumentation libraries in OCaml","archived":false,"fork":false,"pushed_at":"2025-03-14T00:39:42.000Z","size":3951,"stargazers_count":24,"open_issues_count":0,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-16T00:14:43.692Z","etag":null,"topics":["catapult","ocaml","tef","tracing","tracy"],"latest_commit_sha":null,"homepage":"https://c-cube.github.io/ocaml-trace/","language":"OCaml","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/c-cube.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":null,"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":"2023-06-09T01:26:56.000Z","updated_at":"2025-03-14T00:39:45.000Z","dependencies_parsed_at":"2023-10-04T23:47:47.637Z","dependency_job_id":"4d7d923a-ac01-464c-a12f-1e9f0e1606ff","html_url":"https://github.com/c-cube/ocaml-trace","commit_stats":null,"previous_names":["c-cube/trace","c-cube/ocaml-trace"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/c-cube%2Focaml-trace","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/c-cube%2Focaml-trace/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/c-cube%2Focaml-trace/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/c-cube%2Focaml-trace/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/c-cube","download_url":"https://codeload.github.com/c-cube/ocaml-trace/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243830949,"owners_count":20354854,"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":["catapult","ocaml","tef","tracing","tracy"],"created_at":"2024-08-04T15:01:31.819Z","updated_at":"2025-03-16T21:31:07.603Z","avatar_url":"https://github.com/c-cube.png","language":"OCaml","readme":"\n# Trace\n\n[![Build and Test](https://github.com/c-cube/ocaml-trace/actions/workflows/main.yml/badge.svg)](https://github.com/c-cube/ocaml-trace/actions/workflows/main.yml)\n\nThis small library provides basic types that can be used to instrument\na library or application, either by hand or via a ppx.\n\n## Features\n\n- [x] spans\n- [x] messages\n- [x] counters\n- [ ] other metrics?\n- [x] ppx to help instrumentation\n\n## Usage\n\nTo instrument your code, you can simply add `trace` to your dune/opam files, and then\nwrite code like such:\n\n```ocaml\nlet f x =\n  Trace.with_span ~__FILE__ ~__LINE__ \"inside-f\" @@ fun _sp -\u003e\n  (* … code for f *)\n\nlet g x =\n  Trace.with_span ~__FILE__ ~__LINE__ \"inside-g\" @@ fun _sp -\u003e\n  let y = f x in\n  (* … code for f *)\n\nlet () =\n  Some_trace_backend.setup () @@ fun () -\u003e\n  let result = g 42 in\n  print_result result\n```\n\nThe file `test/t1.ml` follows this pattern, using `trace-tef` as a simple backend\nthat emits one JSON object per span/message:\n\n```ocaml\nlet run () =\n  Trace.set_process_name \"main\";\n  Trace.set_thread_name \"t1\";\n\n  let n = ref 0 in\n\n  for _i = 1 to 50 do\n    Trace.with_span ~__FILE__ ~__LINE__ \"outer.loop\" @@ fun _sp -\u003e\n    for _j = 2 to 5 do\n      incr n;\n      Trace.with_span ~__FILE__ ~__LINE__ \"inner.loop\" @@ fun _sp -\u003e\n      Trace.messagef (fun k -\u003e k \"hello %d %d\" _i _j);\n      Trace.message \"world\";\n      Trace.counter_int \"n\" !n\n    done\n  done\n\nlet () =\n  Trace_tef.with_setup ~out:(`File \"trace.json\") () @@ fun () -\u003e\n  run ()\n```\n\nAfter running this, the file \"trace.json\" will contain something like:\n```json\n[{\"pid\":2,\"name\":\"process_name\",\"ph\":\"M\",\"args\": {\"name\":\"main\"}},\n{\"pid\":2,\"tid\": 3,\"name\":\"thread_name\",\"ph\":\"M\",\"args\": {\"name\":\"t1\"}},\n{\"pid\":2,\"cat\":\"\",\"tid\": 3,\"ts\": 2.00,\"name\":\"hello 1 2\",\"ph\":\"I\"},\n{\"pid\":2,\"cat\":\"\",\"tid\": 3,\"ts\": 3.00,\"name\":\"world\",\"ph\":\"I\"},\n{\"pid\":2,\"tid\":3,\"ts\":4.00,\"name\":\"c\",\"ph\":\"C\",\"args\": {\"n\":1}},\n…\n```\n\nOpening it in https://ui.perfetto.dev we get something like this:\n\n![screenshot of perfetto UI](media/ui.png)\n\n## ppx_trace\n\nOn OCaml \u003e= 4.12, and with `ppxlib` installed, you can install `ppx_trace`.\nThis is a preprocessor that will rewrite like so:\n\n```ocaml\nlet%trace f x y z =\n  do_sth x;\n  do_sth y;\n  begin\n    let%trace () = \"sub-span\" in\n    do_sth z\n  end\n```\n\nThis more or less corresponds to:\n\n```ocaml\nlet f x y z =\n  let _trace_span = Trace_core.enter_span ~__FILE__ ~__LINE__ \"Foo.f\" in\n  match\n    do_sth x;\n    do_sth y;\n    begin\n      let _trace_span = Trace_core.enter_span ~__FILE__ ~__LINE__ \"sub-span\" in\n      match do_sth z with\n      | res -\u003e\n        Trace_core.exit_span _trace_span;\n        res\n      | exception e -\u003e\n        Trace_core.exit_span _trace_span\n        raise e\n    end;\n  with\n  | res -\u003e\n    Trace_core.exit_span _trace_span\n    res\n  | exception e -\u003e\n    Trace_core.exit_span _trace_span\n    raise e\n```\n\nAlternatively, a name can be provided for the span, which is useful if you want\nto access it and use functions like `Trace.add_data_to_span`:\n\n\n```ocaml\nlet%trace f x y z =\n  do_sth x;\n  do_sth y;\n  begin\n    let%trace _sp = \"sub-span\" in\n    do_sth z;\n    Trace.add_data_to_span _sp [\"x\", `Int 42]\n  end\n```\n\n### Dune configuration\n\nIn your `library` or `executable` stanza, add: `(preprocess (pps ppx_trace))`.\nThe dependency on `trace.core` is automatically added. You still need to\nconfigure a backend to actually do collection.\n\n## Backends\n\nConcrete tracing or observability formats such as:\n\n- [x] Fuchsia (see [the spec](https://fuchsia.dev/fuchsia-src/reference/tracing/trace-format) and [tracing](https://github.com/janestreet/tracing).\n        Can be opened in https://ui.perfetto.dev)\n- Catapult\n  * [x] light bindings here with `trace-tef`.\n        (Can be opened in https://ui.perfetto.dev)\n  * [x] backend for [tldrs](https://github.com/imandra-ai/tldrs), a\n        small rust daemon that aggregates TEF traces from multiple processes/clients\n        into a single `.jsonl` file\n  * [x] [tldrs](https://github.com/imandra-ai/tldrs), to collect TEF traces from multiple processes in a clean way.\n        This requires the rust `tldrs` program to be in path.\n  * ~~[ ] richer bindings with [ocaml-catapult](https://github.com/imandra-ai/catapult),\n        with multi-process backends, etc.~~ (subsumed by tldrs)\n- [x] Tracy (see [ocaml-tracy](https://github.com/imandra-ai/ocaml-tracy), more specifically `tracy-client.trace`)\n- [x] Opentelemetry (see [ocaml-opentelemetry](https://github.com/imandra-ai/ocaml-opentelemetry/), in `opentelemetry.trace`)\n- [ ] landmarks?\n- [ ] Logs (only for messages, obviously)\n\n## Subscribers\n\nThe library `trace.subscriber` defines composable _subscribers_, which are sets of callbacks\nthat consume tracing events.\nMultiple subscribers can be aggregated together (with events being dispatched to all of them)\nand be installed as a normal _collector_.\n","funding_links":[],"categories":["OCaml"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fc-cube%2Focaml-trace","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fc-cube%2Focaml-trace","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fc-cube%2Focaml-trace/lists"}