MCPcopy Index your code
hub / github.com/DataDog/lading

github.com/DataDog/lading @v0.32.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.32.0 ↗ · + Follow
1,861 symbols 5,236 edges 186 files 476 documented · 26%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

lading - A tool for measuring the performance of long-running programs.

The lading project is a tool for measuring the performance behavior of long-running programs -- daemons, often -- using synthetic, repeatable load generation across a variety of protocols. The ambition is to be a worry-free component of a larger performance testing strategy for complex programs. The Datadog Agent project uses lading in their 'Regression Detector' tests.

Operating Model

lading operates on three conceptual components:

  • generators,
  • target and
  • blackholes

A "generator" in lading is responsible for creating load and "pushing" it into the target. The "target" in is the program that lading runs as a sub-process, collecting resource consumption data about the target from the operating system but also self-telemetry regarding generation. The "blackhole" exists for targets to push load into, when necessary, allowing for a target to be run and examined by lading without including external programs or APIs into the setup.

As much as possible lading pre-computes any generator and blackhole payloads, intending to minimize runtime overhead compared to the target program. Users must provide a seed to lading -- see below -- ensuring that payloads are generated in a repeatable manner across lading runs. While pre-computation does mean that lading is capable of outpacing many targets with minimal runtime interference it does also mean higher memory use compared to other load generation tools.

Configuration

The configuration of lading is split between a configuration file in YAML format and command-line options. Generators and blackholes are configured in the config file, targets on the command line. This is, at first glance, awkward but does allow for lading to be used in dynamic environments like CI without foreknowledge of the target.

That "push" can be as direct as network IO into the target or as indirect as doing file operations for a target who's tracing with BPF.

Consider the following lading.yaml:

generator:
  - http:
      seed: [2, 3, 5, 7, 11, 13, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137]
      target_uri: "http://localhost:8282/"
      bytes_per_second: "100 MiB"
      parallel_connections: 10
      method:
        post:
          variant: "fluent"
          maximum_prebuild_cache_size_bytes: "256 MiB"
      headers: {}

blackhole:
  - http:
      binding_addr: "0.0.0.0:8080"

In this setup lading is configured to run one generator and one blackhole. In general, at least one generator is required and zero or more blackholes are. The generator here, named "http", uses a fixed seed to repeatably produce fluent's forward protocol instances at 100 MiB per second into the target, with a pre-built size of 256 MiB. That is, lading will attempt to push at a fixed throughput, although the target might not be able to cope with that load and lading will consume 256 MiB of RAM to accommodate pre-build payloads. The blackhole in this configuration responds with an empty body 200 OK.

lading supports three types of targets, binary launch mode, PID watch mode, and container watch mode.

In binary launch mode, lading acts like a wrapper around the target. To use this mode, one specifies where on disk the configuration is, the path to the target and its arguments. --target-stderr-path and --target-stdout-path allow the target's stdout, stderr to be forwarded into files. At runtime lading will output diagnostic information on its stdout about the current state of the target.

In PID watch mode, lading monitors a process that is already running on the system. lading does not handle any target orchestration in this mode. The target should be launched before running lading and terminated once lading exits.

Container watch mode is identical to PID watch mode except that the docker socket is polled to find the container's PID instead of the user needing to specify it manually.

The data lading captures at runtime can be pulled by polling lading's prometheus endpoint -- configurable with --prometheus-addr / --prometheus-path -- or can be written to disk by lading by specifying --capture-path. The captured data, when written to disk, is newline delimited json payloads.

Logs about lading's operation can be controlled using the standard RUST_LOG environment variable. eg RUST_LOG=debug ./lading will emit logs at debug and above (ie, info, warn, error).

Development Setup

lading requires the protobuf compiler to build. See installation instructions from the protobuf docs.

For criterion benchmarks, you can run them via cargo bench. cargo-criterion is a more advanced cargo extension that provides historical (ie baseline) tracking functionality.

When using lading to monitor a linux process that is more privileged than lading is (eg, a container), some metrics are unavailable due to security restrictions.

To give lading extra permissions needed, setcap can be used to grant the binary cap_sys_ptrace. Eg: sudo setcap cap_sys_ptrace=ep ./target/debug/lading

Binaries in-tree

  • lading -- the main tool capable of generating load, blackholes, observers, etc. Everything discussed above.
  • captool -- Useful to inspect the resulting capture.json file which contains metrics generated by a lading run.
  • payloadtool -- Useful when writing/changing experiments to validate that a specified payload behaves as expected.

How to get a build (besides building from source)

Container Releases

https://github.com/DataDog/lading/pkgs/container/lading

Docker

For arm (replace platform if needed):

docker build -f arm64.Dockerfile . --tag [TAG NAME] --platform linux/arm64

For x86_64:

docker build -f amd64.Dockerfile . --tag [TAG NAME] --platform linux/amd64

Documentation

Contributing

See Contributing.

License

Licensed under the MIT license.

Extension points exported contracts — how you extend this code

Serialize (Interface)
To serialize into bytes [17 implementers]
lading_payload/src/lib.rs
OutputFormat (Interface)
Trait for output format implementations Implementations of this trait handle the serialization and writing of metrics t [3 …
lading_capture/src/formats.rs
Clock (Interface)
The `Clock` used for every throttle [1 implementers]
lading_throttle/src/lib.rs
StatefulLogsService (Interface)
(no doc) [1 implementers]
lading/src/proto/datadog.intake.stateful.rs
Generator (Interface)
Generate instances of `Self::Output` from source of randomness. NOTE this generator is suitable for use only when the s [7 …
lading_payload/src/lib.rs
TickInterval (Interface)
Interval abstraction for tick-based operations [2 implementers]
lading_capture/src/manager.rs
SizedGenerator (Interface)
Generate instances of `Self::Output` from source of randomness, constrained to byte budgets. NOTE this generator is sui [10 …
lading_payload/src/lib.rs
Clock (Interface)
Clock abstraction for controllable time in tests Following the pattern from `lading_throttle`, allows production code t [2 …
lading_capture/src/manager.rs

Core symbols most depended-on inside this repo

new
called by 968
lading_throttle/src/stable.rs
push
called by 205
lading_capture/src/formats/parquet.rs
get
called by 192
lading/src/bin/lading.rs
clone
called by 184
lading/src/proto/datadog.intake.stateful.rs
clone
called by 171
lading_signal/src/lib.rs
len
called by 159
lading_payload/src/block.rs
iter
called by 113
lading/src/generator/splunk_hec/acknowledgements.rs
recv
called by 56
lading_signal/src/lib.rs

Shape

Function 675
Method 574
Class 403
Enum 199
Interface 10

Languages

Rust99%
Python1%

Modules by API surface

lading_payload/src/opentelemetry/trace.rs76 symbols
lading_payload/src/common/strings/string_list_pool.rs76 symbols
lading_capture/src/accumulator.rs61 symbols
lading/src/generator/file_gen/logrotate_fs/model.rs44 symbols
lading/src/generator/common.rs42 symbols
lading_capture/src/manager/state_machine.rs36 symbols
lading/src/proto/datadog.intake.stateful.rs35 symbols
lading/src/generator/process_tree.rs34 symbols
lading/src/config.rs34 symbols
lading_payload/src/procfs.rs32 symbols
lading_capture/src/manager.rs32 symbols
lading_payload/src/templated_json/resolver.rs31 symbols

For agents

$ claude mcp add lading \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact