Skip to content

Commit

Permalink
[feature] hyperledger-iroha#4083: Add pprof-rs support (hyperledger-i…
Browse files Browse the repository at this point in the history
…roha#4250)

Signed-off-by: Shanin Roman <[email protected]>
  • Loading branch information
Erigara authored Feb 13, 2024
1 parent 2723e40 commit 86fb216
Show file tree
Hide file tree
Showing 14 changed files with 366 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
**/target
Dockerfile
Dockerfile*
9 changes: 7 additions & 2 deletions .github/workflows/iroha2-ci-image.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
name: I2::CI::Publish

on: workflow_dispatch
on:
workflow_dispatch:
inputs:
IROHA2_CI_DOCKERFILE:
required: true
default: Dockerfile.build

jobs:
dockerhub:
Expand All @@ -17,6 +22,6 @@ jobs:
push: true
tags: hyperledger/iroha2-ci:nightly-2023-06-25
labels: commit=${{ github.sha }}
file: Dockerfile.build
file: ${{ github.event.inputs.IROHA2_CI_DOCKERFILE }}
# This context specification is required
context: .
64 changes: 64 additions & 0 deletions .github/workflows/iroha2-profiling-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: I2::Profiling::Publish

on:
workflow_dispatch:
inputs:
IROHA2_IMAGE_TAG:
required: true
default: stable
IROHA2_IMAGE_RELEASE:
required: true
IROHA2_DOCKERFILE:
required: true
default: Dockerfile.glibc
IROHA2_PROFILE:
required: true
default: profiling
IROHA2_RUSTFLAGS:
required: false
default: -C force-frame-pointers=on
IROHA2_FEATURES:
required: false
default: profiling
IROHA2_CARGOFLAGS:
required: false
default: -Z build-std

jobs:
registry:
runs-on: [self-hosted, Linux, iroha2-dev-push]
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to Soramitsu Harbor
uses: docker/login-action@v3
with:
registry: docker.soramitsu.co.jp
username: ${{ secrets.HARBOR_USERNAME }}
password: ${{ secrets.HARBOR_TOKEN }}
- name: Set up Docker Buildx
id: buildx
if: always()
uses: docker/setup-buildx-action@v3
with:
install: true
- name: Build and push iroha2:profiling-image
uses: docker/build-push-action@v5
if: always()
with:
push: true
tags: |
hyperledger/iroha2:${{ github.event.inputs.IROHA2_IMAGE_TAG }}-${{ github.event.inputs.IROHA2_IMAGE_RELEASE }}-profiling
docker.soramitsu.co.jp/iroha2/iroha2:${{ github.event.inputs.IROHA2_IMAGE_TAG }}-${{ github.event.inputs.IROHA2_IMAGE_RELEASE }}-profiling
labels: commit=${{ github.sha }}
build-args: |
"PROFILE=${{ github.event.inputs.IROHA2_PROFILE }}"
"RUSTFLAGS=${{ github.event.inputs.IROHA2_RUSTFLAGS }}"
"FEATURES=${{ github.event.inputs.IROHA2_FEATURES }}"
"CARGOFLAGS=${{ github.event.inputs.IROHA2_CARGOFLAGS }}"
file: ${{ github.event.inputs.IROHA2_DOCKERFILE }}
# This context specification is required
context: .
48 changes: 48 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,54 @@ tokio-console http://127.0.0.1:5555

</details>

### Profiling

<details> <summary> Expand to learn ho to profile iroha. </summary>

To optimize performance it's useful to profile iroha.

To do that you should compile iroha with `profiling` profile and with `profiling` feature:

```bash
RUSTFLAGS="-C force-frame-pointers=on" cargo +nightly -Z build-std build --target your-desired-target --profile profiling --features profiling
```

Then start iroha and attach profiler of your choice to the iroha pid.

Alternatively it's possible to build iroha inside docker with profiler support and profile iroha this way.

```bash
docker build -f Dockerfile.glibc --build-arg="PROFILE=profiling" --build-arg='RUSTFLAGS=-C force-frame-pointers=on' --build-arg='FEATURES=profiling' --build-arg='CARGOFLAGS=-Z build-std' -t iroha2:profiling .
```

E.g. using perf (available only on linux):

```bash
# to capture profile
sudo perf record -g -p <PID>
# to analyze profile
sudo perf report
```

To be able to observe profile of the executor during iroha profiling, executor should be compiled without stripping symbols.
It can be done by running:

```bash
# compile executor without optimizations
cargo run --bin iroha_wasm_builder_cli -- build ./path/to/executor --outfile executor.wasm
```

With profiling feature enabled iroha exposes endpoint to scrap pprof profiles:

```bash
# profile iroha for 30 seconds and get protobuf profile
curl host:port/debug/pprof/profile?seconds=30 -o profile.pb
# analyze profile in browser (required installed go)
go tool pprof -web profile.pb
```

</details>

## Style Guides

Please follow these guidelines when you make code contributions to our project:
Expand Down
104 changes: 103 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,7 @@ members = [
inherits = "release"
strip = "symbols"
lto = true

[profile.profiling]
inherits = "release"
debug = "limited"
41 changes: 19 additions & 22 deletions Dockerfile.glibc
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
#base stage
FROM archlinux:base-devel AS builder
# base stage
FROM debian:bookworm-slim AS builder

# Force-sync packages, install archlinux-keyring, repopulate keys
RUN pacman -Syy
RUN pacman -S archlinux-keyring --noconfirm --disable-download-timeout
RUN rm -rf /etc/pacman.d/gnupg/* && pacman-key --init && pacman-key --populate archlinux
# install required packages
RUN apt-get update -y && \
apt-get install -y curl build-essential mold

# Install updates
RUN pacman -Syu --noconfirm --disable-download-timeout

# Set up Rust toolchain
RUN pacman -S rustup mold wget --noconfirm --disable-download-timeout
# set up Rust toolchain
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y
ENV PATH="/root/.cargo/bin:${PATH}"
RUN rustup toolchain install nightly-2023-06-25
RUN rustup default nightly-2023-06-25
RUN rustup target add wasm32-unknown-unknown
Expand All @@ -19,15 +16,18 @@ RUN rustup component add rust-src
# builder stage
WORKDIR /iroha
COPY . .
RUN mold --run cargo build --target x86_64-unknown-linux-gnu --profile deploy
ARG PROFILE="deploy"
ARG RUSTFLAGS=""
ARG FEATURES=""
ARG CARGOFLAGS=""
RUN RUSTFLAGS="${RUSTFLAGS}" mold --run cargo ${CARGOFLAGS} build --target x86_64-unknown-linux-gnu --profile "${PROFILE}" --features "${FEATURES}"

# final image
FROM alpine:3.18
FROM debian:bookworm-slim

ENV GLIBC_REPO=https://github.com/sgerrand/alpine-pkg-glibc
ENV GLIBC_VERSION=2.35-r1
ARG PROFILE="deploy"
ARG STORAGE=/storage
ARG TARGET_DIR=/iroha/target/x86_64-unknown-linux-gnu/deploy
ARG TARGET_DIR=/iroha/target/x86_64-unknown-linux-gnu/${PROFILE}
ENV BIN_PATH=/usr/local/bin/
ENV CONFIG_DIR=/config
ENV IROHA2_CONFIG_PATH=$CONFIG_DIR/config.json
Expand All @@ -39,12 +39,9 @@ ENV UID=1001
ENV GID=1001

RUN set -ex && \
apk --update add libstdc++ curl ca-certificates gcompat && \
for pkg in glibc-${GLIBC_VERSION} glibc-bin-${GLIBC_VERSION}; \
do curl -sSL ${GLIBC_REPO}/releases/download/${GLIBC_VERSION}/${pkg}.apk -o /tmp/${pkg}.apk; done && \
apk add --force-overwrite --allow-untrusted /tmp/*.apk && \
rm -v /tmp/*.apk && \
addgroup -g $GID $USER && \
apt-get update -y && \
apt-get install -y curl ca-certificates && \
addgroup --gid $GID $USER && \
adduser \
--disabled-password \
--gecos "" \
Expand Down
5 changes: 5 additions & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ workspace = true

[features]
default = ["bridge", "telemetry", "schema-endpoint"]
# Enables profiling endpoint
profiling = ["pprof"]

# Support interoperability with popular blockchain networks (Substrate, Ether, etc.)
bridge = ["iroha_core/bridge"]
Expand Down Expand Up @@ -80,6 +82,9 @@ dashmap = { workspace = true }
thread-local-panic-hook = { version = "0.1.0", optional = true }
uuid = { version = "1.4.1", features = ["v4"] }

# TODO: switch to original crate once fix is merged (https://github.com/tikv/pprof-rs/pull/241)
pprof = { git = " https://github.com/Erigara/pprof-rs", branch = "fix_pointer_align", optional = true, default-features = false, features = ["protobuf-codec", "frame-pointer", "cpp"] }

[dev-dependencies]
serial_test = "2.0.0"

Expand Down
Loading

0 comments on commit 86fb216

Please sign in to comment.