Skip to content

ahrefs/devkit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

6faa0c5 · Apr 4, 2025
Oct 12, 2024
Dec 12, 2023
Oct 9, 2019
Dec 20, 2018
Jul 18, 2023
Jan 20, 2021
Sep 25, 2023
Sep 27, 2022
Mar 2, 2021
Aug 4, 2018
Aug 10, 2018
Jun 27, 2017
Jun 27, 2017
Jul 16, 2019
Mar 23, 2018
Sep 27, 2017
Sep 27, 2017
Oct 17, 2024
Jan 3, 2019
Nov 14, 2024
Nov 12, 2024
Oct 8, 2019
Sep 27, 2016
Jun 19, 2014
Apr 4, 2025
Jul 28, 2020
Sep 24, 2024
Oct 17, 2024
Mar 20, 2017
May 1, 2018
May 11, 2018
Oct 8, 2019
May 2, 2018
Mar 2, 2021
Jun 7, 2019
Jul 20, 2016
Aug 6, 2014
Jul 18, 2017
Jan 26, 2016
May 23, 2017
Jun 14, 2024
Feb 14, 2024
Jul 2, 2019
Nov 12, 2024
Nov 12, 2024
Oct 22, 2024
Feb 16, 2024
Sep 26, 2017
Sep 26, 2017
Feb 14, 2024
Jul 26, 2024
Jul 17, 2023
Jul 12, 2022
Oct 4, 2018
Aug 25, 2016
Aug 25, 2016
Oct 17, 2024
Apr 2, 2020
Apr 4, 2025
Apr 4, 2025
Aug 20, 2017
Apr 14, 2011
Feb 14, 2024
Dec 20, 2018
Sep 20, 2019
Aug 20, 2017
Nov 21, 2011
Feb 14, 2024
Feb 14, 2024
Oct 17, 2024
Oct 25, 2024
Oct 25, 2024
May 23, 2017
Apr 11, 2023
Nov 7, 2024
Oct 14, 2024
Oct 14, 2024
Oct 14, 2024
Jan 14, 2021
Jan 14, 2021
Jul 8, 2015
Jul 8, 2015
Sep 15, 2023
Sep 15, 2023
Jan 10, 2019
Feb 14, 2024
Jun 12, 2014
Feb 14, 2024
Nov 3, 2023
Nov 3, 2023
Apr 4, 2025
Jun 14, 2024
Jan 3, 2019
Mar 13, 2025
Jun 26, 2017
Jun 26, 2017
Jan 12, 2022
Jan 10, 2020
Nov 15, 2024

Repository files navigation

devkit

Build Status

General purpose OCaml library (development kit) Copyright (c) 2009 Ahrefs Released under the terms of LGPL-2.1 with OCaml linking exception.

Usage

opam install devkit

Tracing

Devkit's Web module includes both simple, configurable, local tracing support, as well as distributed tracing support via OpenTelemetry.

To use local tracing, we use the mechanism provided by ocaml-trace: by default, the tracing calls in devkit are a no-op; but if the top-level application containing devkit installs and configures a "tracing backend" at runtime, then devkit's web-requests will each produce timed traces.

As an example, using trace-tef as a backend to produce a json file:

open Devkit

let run () =
  let resp = Web.http_request `GET "http://icanhazip.com" in
  (* ... *)

let () =
  Trace_tef.with_setup ~out:(`File "trace.json") () @@ fun () ->
  run ()

For distributed traces, you'll both need to configure an OpenTelemetry backend for ocaml-trace at runtime (to collect devkit's own traces); and you will most likely also want to ensure your own application's traces (using either ocaml-trace or the full ocaml-opentelemetry) are properly configured to correctly appear as the parent of devkit's traces.

Configuring an OpenTelemetry backend for the traces themselves is as simple wrapping your top-level application in a call to Opentelemetry_trace.setup_with_otel_backend or the like. That will configure both OpenTelemetry's collector and the ocaml-trace backend.

Then, to ensure that parentage is correctly propagated across your distributed architecture, devkit can produce a W3C Trace Context traceparent HTTP header. To ensure that it produces the correct traceparent, however, we depend upon 'ambient context'. For this to function properly, you'll need to follow the detailed instructions in the ocaml-ambient-context documentation.

Once thus configured, devkit will check Opentelemetry.Scope.get_ambient_scope before each HTTP request, and use the ambient tracing-span as the parent of the web-request's span; which will itself then be propagated to the remote service via the traceparent HTTP header.

As an example, if your top-level application is using Lwt, and using cohttp as the OpenTelemetry backend:

open Devkit

let run () =
  let* resp = Web.http_request_lwt `GET "http://icanhazip.com" in
  (* ... *)

let () =
  Ambient_context.set_storage_provider (Ambient_context_lwt.storage ()) ;
  Opentelemetry_trace.setup_with_otel_backend
    (Opentelemetry_client_cohttp_lwt.create_backend ())
  @@ fun () ->
  Lwt_main.run @@ fun () ->
  run ()

Development

Install OCaml dependencies in your current / global switch:

opam install . --deps-only

Or to install them in a new, directory-local switch:

opam switch create . --deps-only --no-install
opam install . --deps-only --with-test

External dependencies:

opam list -s -e --resolve=devkit

To update ragel-generated code:

aptitude install ragel
make -B gen_ragel

To update metaocaml-generated code:

opam exec --switch=4.07.1+BER -- make gen_metaocaml